Android Service基本用法

Service的概念

  • 1.Service作為安卓的四大組件之一,固然是每一位安卓開(kāi)發(fā)者必須掌握的一個(gè)知識(shí)點(diǎn)。雖然它沒(méi)有Activity的使用頻繁,但也是日常開(kāi)發(fā)經(jīng)常用到的涩蜘。

  • 2.通過(guò)名字我們知道,它是服務(wù)的意思锋边。而且通常是"默默"的為我們服務(wù)的皱坛。為什么說(shuō)是默默,因?yàn)樗⒉幌馎ctivity一樣豆巨,能夠被我們看到剩辟。通常,它用于在后臺(tái)為我們執(zhí)行一些耗時(shí)往扔,或者需要長(zhǎng)時(shí)間執(zhí)行的一些操作的贩猎。下面讓我們來(lái)看看它的基本用法。

Service的創(chuàng)建

  • 1.任何一個(gè)對(duì)象萍膛,想要發(fā)揮其作用吭服,那么就應(yīng)該首先創(chuàng)建出來(lái)。Service的創(chuàng)建和Activity類似蝗罗,也是通過(guò)Intent來(lái)實(shí)現(xiàn)的艇棕。而且既然是安卓四大組件之一,那么它也需要在清單文件中進(jìn)行注冊(cè)的串塑。下面沼琉,看一下一個(gè)簡(jiǎn)單的創(chuàng)建Service的例子:
public class SimpleService extends Service {

    public static final String TAG = "SimpleService";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
  • 2.首先,創(chuàng)建一個(gè)類SimpleService繼承自Service,然后重寫(xiě)它的onCreate桩匪,onStartCommand打瘪,onDestroy方法,并分別在它們的方法體中打入Log日志。其中onBind方法是默認(rèn)實(shí)現(xiàn)的闺骚,具體作用后面會(huì)講到彩扔。然后呢,千萬(wàn)不要忘記要在清單文件中注冊(cè)它僻爽,其實(shí)如果你是通過(guò)Android Studio直接new了一個(gè)Service的話虫碉,Android Studio會(huì)默認(rèn)幫助你在清單文件中添加對(duì)該Service的注冊(cè),代碼如下:
<service android:name=".ui.main.SimpleService"
            android:enabled="true"
            android:exported="true"/>

我直接在我之前做的一個(gè)項(xiàng)目中新建的进泼,所以不要在意包路徑的命名蔗衡,就是包名點(diǎn)類名纤虽。細(xì)心的朋友可能看到了下面還有兩個(gè)屬性乳绕。其中enabled屬性,是指該服務(wù)是否能夠被實(shí)例化逼纸。如果設(shè)置為true洋措,則能夠被實(shí)例化,否則不能被實(shí)例化杰刽,默認(rèn)值是true菠发。一般情況下,我們都會(huì)需要實(shí)例化贺嫂,所以也可以選擇不設(shè)置滓鸠。而exported屬性用于指示該服務(wù)是否能夠被其他應(yīng)用程序組件調(diào)用或跟它交互。如果設(shè)置為true第喳,則能夠被調(diào)用或交互(通常如果一個(gè)服務(wù)需要跨進(jìn)程使用需要這么設(shè)置)糜俗,否則不能。設(shè)置為false時(shí)曲饱,只有同一個(gè)應(yīng)用程序的組件或帶有相同用戶ID的應(yīng)用程序才能啟動(dòng)或綁定該服務(wù)悠抹。

  • 3.接下來(lái)創(chuàng)建一個(gè)StartActivity,用于在其中創(chuàng)建SimpleService對(duì)象扩淀。代碼如下:
public class StartActivity extends AppCompatActivity implements View.OnClickListener {

    private Button startBtn, stopBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);

        startBtn = (Button) findViewById(R.id.btn_start_service);
        stopBtn = (Button) findViewById(R.id.btn_stop_service);
     
        startBtn.setOnClickListener(this);
        stopBtn.setOnClickListener(this);  
    }

    @Override
    public void onClick(View v) {
        if (v != null) {
            switch (v.getId()) {
                case R.id.btn_start_service:
                    Intent startIntent = new Intent(this, SimpleService.class);
                    startService(startIntent);
                    break;
                case R.id.btn_stop_service:
                    Intent stopIntent = new Intent(this, SimpleService.class);
                    stopService(stopIntent);
                    break;          
            }
        }
    }
}

StartActivity的xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.kitty.android.ui.main.StartActivity">

    <Button
        android:id="@+id/btn_start_service"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="Start Service"/>
    <Button
        android:id="@+id/btn_destroy_service"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="Destroy Service"/>
</LinearLayout>
  • 4.很簡(jiǎn)單楔敌,就是添加兩個(gè)按鈕,分別用于啟動(dòng)Service和停止Service驻谆÷汛眨可以看到,創(chuàng)建一個(gè)Service的方法非常簡(jiǎn)單胜臊,就是和創(chuàng)建Activity類似勺卢,創(chuàng)建一個(gè)Intent對(duì)象,然后通過(guò)startService方法開(kāi)啟一個(gè)服務(wù)区端。然后同樣的值漫,通過(guò)stopService方法來(lái)停止一個(gè)服務(wù)。為了證明方法的正確性织盼,我們先點(diǎn)擊startBtn杨何,看一下Logcat中的日志截圖酱塔,如下所示:
servicestart.png

由此可以看出,當(dāng)通過(guò)startService方法開(kāi)啟一個(gè)服務(wù)的時(shí)候危虱,會(huì)執(zhí)行Service的onCreate和onStartCommand方法羊娃。接下來(lái),我們?cè)俅吸c(diǎn)擊一下 start按鈕埃跷,再來(lái)看一下Loacat的日志:

restartservice.png

這一次蕊玷,只執(zhí)行了onStartCommand方法,由此我們可以得出結(jié)論弥雹,當(dāng)一個(gè)Service被創(chuàng)建以后垃帅,再次調(diào)用startService方法,Service是不會(huì)被重新創(chuàng)建的剪勿,而是會(huì)重新執(zhí)行onStartCommand方法贸诚。無(wú)論我們點(diǎn)擊多少次start按鈕,始終只會(huì)執(zhí)行onStartCommand方法厕吉。

以上是服務(wù)的創(chuàng)建酱固。接下來(lái),我們點(diǎn)擊stop按鈕头朱,logcat日志如下:

stopservice.png

可以看到运悲,Service執(zhí)行了onDestroy方法,這時(shí)服務(wù)就已經(jīng)停止了项钮。
以上就是簡(jiǎn)單的創(chuàng)建一個(gè)服務(wù)的流程班眯。然而,在我們?nèi)粘i_(kāi)發(fā)中寄纵,我們經(jīng)常需要在服務(wù)中做一些邏輯操作鳖敷,然后將結(jié)果返回給一個(gè)Activity,即要實(shí)現(xiàn)Service和Activity的通信程拭,接下來(lái)定踱,讓我們看看如何讓二者建立起聯(lián)系。

Service與Activity之間的通信

在上面的介紹中恃鞋,我們只是實(shí)現(xiàn)了在Activity中開(kāi)啟一個(gè)服務(wù)崖媚,然而服務(wù)開(kāi)啟了就和這個(gè)Activity沒(méi)什么聯(lián)系了。其實(shí)二者是可以繼續(xù)保持聯(lián)絡(luò)的恤浪,還記得前面提到的一個(gè)onBind方法吧畅哑,其實(shí)它就是Service與Activity之間建立通信的橋梁。現(xiàn)在我們修改一下前面的代碼水由,SimpleService代碼修改如下:

public class SimpleService extends Service {

    public static final String TAG = "SimpleService";

    private SimpleBinder mBinder;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
        mBinder = new SimpleBinder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    @Override
    public IBinder onBind(Intent intent) {
        if (mBinder != null) {
            return mBinder;
        }
        return null;
    }

    class SimpleBinder extends Binder {

        public void doTask() {
            Log.d(TAG, "doTask");
        }
    }
}

現(xiàn)在荠呐,我們?cè)赟impleService中創(chuàng)建了一個(gè)SimpleBinder類,繼承自Binder。然后泥张,在里面創(chuàng)建了一個(gè)doTask方法呵恢,模擬執(zhí)行一個(gè)任務(wù)。然后媚创,我們?cè)僭赟tartActivity中加入兩個(gè)按鈕渗钉,分別用于綁定服務(wù)和解綁服務(wù),XML文件代碼我就不貼了钞钙,就是添兩個(gè)按鈕鳄橘,下面是StartActivity的更改后的代碼:

public class StartActivity extends AppCompatActivity implements View.OnClickListener {

    public static final String TAG = "SimpleService";

    private Button startBtn, stopBtn, bindBtn, unBindBtn;

    private SimpleService.SimpleBinder mBinder;

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, name.toString());
            mBinder = (SimpleService.SimpleBinder) service;
            mBinder.doTask();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, name.toString());
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);

        startBtn = (Button) findViewById(R.id.btn_start_service);
        stopBtn = (Button) findViewById(R.id.btn_stop_service);
        bindBtn = (Button) findViewById(R.id.btn_bind_service);
        unBindBtn = (Button) findViewById(R.id.btn_un_bind_service);

        startBtn.setOnClickListener(this);
        stopBtn.setOnClickListener(this);
        bindBtn.setOnClickListener(this);
        unBindBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v != null) {
            switch (v.getId()) {
                case R.id.btn_start_service:
                    Intent startIntent = new Intent(this, SimpleService.class);
                    startService(startIntent);
                    break;
                case R.id.btn_stop_service:
                    Intent stopIntent = new Intent(this, SimpleService.class);
                    stopService(stopIntent);
                    break;
                case R.id.btn_bind_service:
                    Intent bindIntent = new Intent(this, SimpleService.class);
                    bindService(bindIntent, mConnection, BIND_AUTO_CREATE);
                    break;
                case R.id.btn_un_bind_service:
                    unbindService(mConnection);
                    break;
            }
        }
    }
}

這里,我們創(chuàng)建了一個(gè)ServiceConnection的匿名內(nèi)部類芒炼,并實(shí)現(xiàn)了onServiceConnected和onServiceDisconnected兩個(gè)方法瘫怜。ServiceConnection可以看做是一個(gè)由Activity操作的代表,負(fù)責(zé)與Service進(jìn)行連接焕议,當(dāng)Activity與Service連接成功時(shí)宝磨,會(huì)執(zhí)行onServiceConnected方法弧关,相反的盅安,當(dāng)二者斷開(kāi)連接的時(shí)候,會(huì)執(zhí)行onServiceDisconnected方法世囊。當(dāng)二者連接成功時(shí)别瞭,在onServiceConnected方法中,我們可以獲取到SimpleService中的SimpleBinder的實(shí)例對(duì)象株憾,然后我們就可以調(diào)用其所有的公共方法來(lái)實(shí)現(xiàn)我們想要做的事了蝙寨。

現(xiàn)在我們來(lái)看一下綁定一個(gè)服務(wù)的方法,也是先創(chuàng)建一個(gè)Intent嗤瞎,然后將其作為bindService的第一個(gè)參數(shù)墙歪,第二個(gè)參數(shù)就是我們剛才說(shuō)到的那個(gè)代表ServiceConnection,而第三個(gè)參數(shù)是一個(gè)標(biāo)記贝奇,這里我們傳入BIND_AUTO_CREATE標(biāo)記虹菲,此標(biāo)記表示在Activity和Service建立關(guān)聯(lián)后自動(dòng)創(chuàng)建Service,并執(zhí)行Service中的onCreate方法掉瞳,并不會(huì)執(zhí)行onStartCommand方法毕源。(標(biāo)記不只這一個(gè),可以自行去查閱其他flag的含義)

為了驗(yàn)證剛剛我所說(shuō)的陕习,我們點(diǎn)擊bind按鈕霎褐,并查看logcat日志,如下:

bindservice.png

可以看到该镣,確實(shí)只執(zhí)行了onCreate方法冻璃,并且在ServiceConnection的onServiceConnected中的第一個(gè)參數(shù)返回的其實(shí)就是SimpleService的具體包名路徑。然后接著就執(zhí)行了SimpleBinder中的doTask方法。當(dāng)我們?cè)俅吸c(diǎn)擊bind按鈕省艳,會(huì)發(fā)現(xiàn)歌粥,并沒(méi)有執(zhí)行任何的方法,說(shuō)明了服務(wù)如果一旦與一個(gè)Activity綁定后拍埠,如果沒(méi)有解綁的話失驶,它是不會(huì)重新與這個(gè)Activity進(jìn)行綁定的。

綁定完了枣购,最終我們肯定是需要解綁的嬉探,來(lái)看一下unBind按鈕的操作方法,只有一個(gè)unbindService方法棉圈,需要傳入一個(gè)ServiceConnection參數(shù)涩堤,即我們前面創(chuàng)建的mConnection實(shí)例。點(diǎn)擊unbind按鈕分瘾,看到logcat日志如下:

unbindservice.png

執(zhí)行了onDestroy方法胎围,這是剛剛通過(guò)bindService方法創(chuàng)建的Service就已經(jīng)被摧毀了。

Service創(chuàng)建與摧毀方式的混淆

通過(guò)剛剛上述的描述德召,我們現(xiàn)在知道創(chuàng)建一個(gè)Service的方式有兩種白魂,即通過(guò)startService和bindService的方式。而二者對(duì)Service的摧毀方式分別為stopService和unBindService上岗。那么可能很多人會(huì)疑問(wèn)如果我選擇startService的方式創(chuàng)建福荸,然后選擇unbindService的方式摧毀‰戎溃或者說(shuō)我采用bindService方式創(chuàng)建敬锐,stopService方式摧毀呢。那么我們來(lái)對(duì)每種情況分別驗(yàn)證一下會(huì)發(fā)生什么樣的結(jié)果呆瞻。

我們首先現(xiàn)將SimpleService中的代碼還原成如下?tīng)顟B(tài)台夺。StartActivity中還是四個(gè)按鈕分別對(duì)應(yīng)四個(gè)方法。

public class SimpleService extends Service {

    public static final String TAG = "SimpleService";

    private SimpleBinder mBinder;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
        mBinder = new SimpleBinder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 任務(wù)邏輯
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    @Override
    public IBinder onBind(Intent intent) {
        if (mBinder != null) {
            return mBinder;
        }
        return null;
    }

    class SimpleBinder extends Binder {

        public void doTask() {
            Log.d(TAG, "doTask");
        }
    }
}
  • 1.我們首先點(diǎn)擊一下start按鈕痴脾,然后點(diǎn)擊unbind按鈕颤介,結(jié)果會(huì)發(fā)現(xiàn)程序崩了。
notregister.png

崩潰日志如下明郭,提示非法狀態(tài)異常买窟,接著后面又說(shuō),Service沒(méi)有被注冊(cè)薯定。其實(shí)始绍,很容易理解,就是不看崩潰日志话侄,估計(jì)很多人也猜到了亏推,Service根本就沒(méi)有與任何東西綁定学赛,又何談解綁呢。所以吞杭,這里需要注意盏浇,在使用unbindService方法關(guān)閉一個(gè)服務(wù)時(shí),為防止出現(xiàn)以上的情況芽狗,我們需要在調(diào)用比方法前判斷一下當(dāng)前的Service是否已經(jīng)被綁定绢掰。

針對(duì)這一判斷谷歌并沒(méi)有提供專門(mén)的Api,而我們可以通過(guò)在本地創(chuàng)建一個(gè)變量童擎,當(dāng)服務(wù)被綁定的時(shí)候滴劲,在ServiceConnection的onServiceConnected方法中將其設(shè)為true, 在onServiceDisconnected方法中將其設(shè)為false。這樣的話顾复,如果服務(wù)未被綁定的話班挖,這個(gè)值會(huì)永遠(yuǎn)為false,這樣我們就直接在調(diào)用unbindService方法前做出相應(yīng)的提示芯砸,以防止崩潰產(chǎn)生萧芙。

  • 2.點(diǎn)擊bind按鈕后,再點(diǎn)擊stop按鈕假丧。同樣双揪,看一下logcat日志:
bindstop.png

請(qǐng)相信我,我真的點(diǎn)擊了stop按鈕虎谢,而且不止點(diǎn)擊了一次盟榴。可以看到婴噩,Service并沒(méi)有被摧毀。而當(dāng)我再次點(diǎn)擊unbind按鈕時(shí)羽德,Service才被摧毀几莽。其實(shí)這也很好解釋,舉個(gè)例子吧宅静,施瓦星格拍的終結(jié)者(第二部)不知道大家有沒(méi)有看過(guò)章蚣,施瓦星格扮演的終結(jié)者的使命是保護(hù)男主,他的程序一旦被啟動(dòng)姨夹,就會(huì)一直以保護(hù)男主(完成使命)為目的纤垂,只有消滅了敵人,確保男主可以平安無(wú)事了磷账,他才會(huì)停止保護(hù)男主的行為峭沦。Service就相當(dāng)于施瓦星格,它一旦被綁定逃糟,必須等到一個(gè)結(jié)果來(lái)告訴它"使命"完成了(解綁了)吼鱼,它才會(huì)停止下來(lái)蓬豁。

  • 3.點(diǎn)擊start按鈕后,接著點(diǎn)擊bind按鈕菇肃,然后呢地粪,我們分別單獨(dú)點(diǎn)擊stop和unbind按鈕,發(fā)現(xiàn)Service都不會(huì)被摧毀琐谤,只有在我們兩個(gè)按鈕都點(diǎn)擊了以后(兩個(gè)按鈕的點(diǎn)擊順序無(wú)所謂)蟆技,Service才會(huì)被摧毀。通過(guò)這一樣一個(gè)結(jié)論斗忌,我們可以得出叉瘩,一個(gè)Service,只有在即沒(méi)有和任何Activity綁定又處于停止?fàn)顟B(tài)下的時(shí)候项棠,才可以被摧毀肃廓。

  • 4.最后,還要大家清楚一個(gè)問(wèn)題就是陈哑。當(dāng)你通過(guò)start按鈕妻坝,開(kāi)啟一個(gè)Service后,再次點(diǎn)擊bind按鈕惊窖,只會(huì)執(zhí)行服務(wù)的doTask方法刽宪,也就是Service綁定的方法回調(diào),而不會(huì)執(zhí)行onCreate方法再次創(chuàng)建一個(gè)Service界酒。而同樣的當(dāng)通過(guò)點(diǎn)擊bind按鈕開(kāi)啟一個(gè)服務(wù)后圣拄,再點(diǎn)擊start按鈕,也不會(huì)執(zhí)行onCreate方法毁欣,只會(huì)每次點(diǎn)擊都執(zhí)行onstartCommand方法庇谆,這里在前面也提到過(guò)。

Service的執(zhí)行線程

很多對(duì)Service了解的不是很透徹的同學(xué)凭疮,當(dāng)被問(wèn)到Service運(yùn)行在什么線程中饭耳,很多人都會(huì)第一反應(yīng)是子線程。原因呢执解,因?yàn)榇蠖鄶?shù)人都知道Service通常用來(lái)執(zhí)行一些比較耗時(shí)的后臺(tái)任務(wù)寞肖,既然提到了耗時(shí),那么肯定不會(huì)運(yùn)行在主線程啊衰腌,因?yàn)槟菢拥脑挄?huì)阻塞線程的啊新蟆。其實(shí)呢,并不是這樣的右蕊,Service其實(shí)是運(yùn)行在主線程的琼稻。為了證明我所說(shuō)的,我分別在StartActivity的onCreate方法和SimpleService的onCreate方法中獲取當(dāng)前運(yùn)行的線程的名字和id尤泽,代碼如下:

// Activity的onCreate方法
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);
        Log.d(TAG, "StartActivity-----" + Thread.currentThread().getName() + "--" + Thread.currentThread().getId());  
    }

// Service的onCreate方法
   @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "SimpleService-----" + Thread.currentThread().getName() + "--"Thread.currentThread().getId());     
    }

分別啟動(dòng)Activity和Service,Logcat日志如下:

servicethread.png

可以看到欣簇,Service真的和Activity一樣规脸,是運(yùn)行在主線程的。到這估計(jì)好多人就懵逼了熊咽,這到底是個(gè)什么鬼啊莫鸭,明明是用來(lái)執(zhí)行一些后臺(tái)的耗時(shí)任務(wù)的啊,怎么還運(yùn)行在主線程啊横殴。
其實(shí)被因,這就是不會(huì)融會(huì)貫通的表現(xiàn)。Service確實(shí)運(yùn)行在主線程衫仑,但是我們?nèi)绻麍?zhí)行耗時(shí)操作梨与,我們可以在Service里面開(kāi)啟一個(gè)子線程來(lái)執(zhí)行耗時(shí)任務(wù)啊。那么問(wèn)題又來(lái)了文狱,我們?cè)贏ctivity中就可以創(chuàng)建子線程何必還費(fèi)二遍事開(kāi)始一個(gè)服務(wù)來(lái)創(chuàng)建一個(gè)子線程呢粥鞋。這里就不得不說(shuō)出Service的一個(gè)特性了,那就是不管創(chuàng)建Service的Activity是否被摧毀瞄崇,或者說(shuō)即使退出了應(yīng)用程序呻粹,但只要應(yīng)用的進(jìn)程沒(méi)有被殺死,這個(gè)Service就還會(huì)在運(yùn)行著苏研。而對(duì)于Activity來(lái)說(shuō)等浊,一旦Activity被摧毀,那么在它里面創(chuàng)建的線程也就不存在摹蘑,這樣一來(lái)執(zhí)行的任務(wù)也就停止了筹燕。而如果放在Service中執(zhí)行,即便是關(guān)聯(lián)的Activity被摧毀了衅鹿,那么只要重新與Service進(jìn)行關(guān)聯(lián)撒踪,那么它還是會(huì)獲得原有Service中的Binder實(shí)例的。舉出這樣一個(gè)需求塘安,假設(shè)應(yīng)用需要在進(jìn)程未被殺死的情況下時(shí)刻保持著從服務(wù)器讀取一個(gè)狀態(tài)糠涛,很明顯這時(shí)候就可以用Service來(lái)實(shí)現(xiàn)了啊。

現(xiàn)在兼犯,是不是明白了為什么通常在Service中執(zhí)行一些后臺(tái)的耗時(shí)操作了吧。下面我列舉出一個(gè)例子來(lái)掩飾在Service中開(kāi)啟一個(gè)線程來(lái)執(zhí)行操作:

public class SimpleService extends Service {
    
    private SimpleBinder mBinder;

    @Override
    public void onCreate() {
        super.onCreate();
        mBinder = new SimpleBinder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 任務(wù)邏輯
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        if (mBinder != null) {
            return mBinder;
        }
        return null;
    }

    class SimpleBinder extends Binder {

        public void doTask() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // 任務(wù)邏輯
                }
            }).start();
        }
    }
}

看到了吧集漾,是不是很簡(jiǎn)單切黔!

恍然大悟.png

以上就是Service的一些基礎(chǔ)用法,只有掌握了這些基本用法以后具篇,我們才能更好的利用Service這一組件來(lái)完成我們平時(shí)日常中的開(kāi)發(fā)需求纬霞。特別提醒的是,要根據(jù)場(chǎng)景恰當(dāng)?shù)倪x擇使用Service驱显,不要拿出一個(gè)任務(wù)就用Service來(lái)實(shí)現(xiàn)诗芜,以免造成不必要的開(kāi)銷瞳抓。(PS:Service的用法不單單是這些,至于他的高級(jí)用法日后我會(huì)再寫(xiě)一篇文章的伏恐,敬請(qǐng)期待:⒀啤!翠桦!)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末横蜒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子销凑,更是在濱河造成了極大的恐慌丛晌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斗幼,死亡現(xiàn)場(chǎng)離奇詭異澎蛛,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蜕窿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)谋逻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人渠羞,你說(shuō)我怎么就攤上這事斤贰。” “怎么了次询?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵荧恍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我屯吊,道長(zhǎng)送巡,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任盒卸,我火速辦了婚禮骗爆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蔽介。我一直安慰自己摘投,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布虹蓄。 她就那樣靜靜地躺著犀呼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪薇组。 梳的紋絲不亂的頭發(fā)上外臂,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音律胀,去河邊找鬼宋光。 笑死貌矿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的罪佳。 我是一名探鬼主播逛漫,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼菇民!你這毒婦竟也來(lái)了尽楔?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤第练,失蹤者是張志新(化名)和其女友劉穎阔馋,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體娇掏,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呕寝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了婴梧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片下梢。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖塞蹭,靈堂內(nèi)的尸體忽然破棺而出孽江,到底是詐尸還是另有隱情,我是刑警寧澤番电,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布岗屏,位于F島的核電站,受9級(jí)特大地震影響漱办,放射性物質(zhì)發(fā)生泄漏这刷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一娩井、第九天 我趴在偏房一處隱蔽的房頂上張望暇屋。 院中可真熱鬧,春花似錦洞辣、人聲如沸咐刨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)所宰。三九已至,卻和暖如春畜挥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背婴谱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工蟹但, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留躯泰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓华糖,卻偏偏與公主長(zhǎng)得像麦向,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子客叉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容