Android開發--IntentService的用法,你錯過了什麼

來源:互聯網
上載者:User

標籤:android   開發   intentservice   

IntentService是Android中提供的後台服務類,我們在外部組件中通過Intent向IntentService發送請求命令,之後IntentService逐個執行命令隊列裡的命令,接收到首個命令時,IntentService就開始啟動並開始一條後台線程執行首個命令,接著隊列裡的命令將會被順序執行,最後執行完隊列的所有命令後,服務也隨即停止並被銷毀。

與Service的不同
  1. Service中的程式仍然運行於主線程中,而在IntentService中的程式運行在我們的非同步後台線程中。在接觸到IntentService之前,我在項目中大多是自己寫一個Service,在Service中自己寫一個後台線程去處理相關事務,而這些工作Android其實早已經幫我們封裝的很好。
  2. 在Service中當我的後台服務執行完畢之後需要在外部組件中調用stopService方法銷毀服務,而IntentService並不需要,它會在工作執行完畢後自動銷毀。
IntentService的用法

1.編寫自己的Service類繼承IntentService,並重寫其中的onHandleIntent(Intent)方法,該方法是IntentService的一個抽象方法,用來處理我們通過startService方法開啟的服務,傳入參數Intent就是開啟服務的Intent。在這裡我重寫了一個MyService類去處理後台事務,每一次調用對count加1,並列印log。

package com.example.intentservicetest;import android.app.IntentService;import android.content.Intent;import android.util.Log;public class MyService extends IntentService {    private static final String TAG = MyService.class.getSimpleName();    private int count = 0;    public MyService() {        super(TAG);        // TODO Auto-generated constructor stub    }    @Override    protected void onHandleIntent(Intent intent) {        // TODO Auto-generated method stub        //在這裡添加我們要執行的代碼,Intent中可以儲存我們所需的資料,        //每一次通過Intent發送的命令將被順序執行        count ++;        Log.w(TAG, "count::" + count);    }}

2.註冊我們的服務:接下來在AndroidManifest檔案中的Application標籤下添加我們的服務。

<service android:name="com.example.intentservicetest.MyService" />

3.在外部組件中開啟服務:在這裡我們在Activity中利用Intent迴圈10次開啟服務。

for (int i = 0; i < 10; i++) {        Intent intent = new Intent(MainActivity.this, MyService.class);        startService(intent);}

4.結果輸出:

可以看到在MyService中是按照順序執行我們的請求命令的。

原理分析

1.生命週期函數:
IntentService同樣是繼承於Service的,它也擁有相同的生命週期函數;

  • onCreate:服務建立時調用;
  • onStartCommand(Intent, int, int)方法:在Service源碼可以看到onStart方法是在該方法中被調用的。每次組件通過startService方法啟動服務時調用一次,兩個int型參數,一個是群組識別碼,一個是啟動ID,群組識別碼用來表示當前Intent發送是一次重新發送還是一次從沒成功過的發送。每次調用onStartCommand方法時啟動ID都不同,啟動ID也用來區分不同的命令;
  • onDestroy方法:在服務停止時調用。

2.onCreate方法:首先讓我們看看IntentService源碼中的onCreate方法,

    @Override    public void onCreate() {        super.onCreate();        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");        thread.start();        mServiceLooper = thread.getLooper();        mServiceHandler = new ServiceHandler(mServiceLooper);}

可以看到:在IntentService的onCreate方法中開啟了一個非同步線程HandlerThread來處理我們的請求,並利用Looper和Handler來管理我們的請求命令隊列。關於HandlerThread的用法可以參考以下博文:Android源碼分析–Handler和Looper機制詳解 。

3.如何停止服務
看到了onCreate方法我們就可以明白了,IntentService是如何開啟非同步線程以及如何管理命令隊列的,那麼我們之前曾提到:當後台服務處理結束後,我們並不需要再調用stopService方法銷毀服務,IntentService會自動銷毀,它是如何做到的呢?然我們看看ServiceHandler:

private final class ServiceHandler extends Handler {        public ServiceHandler(Looper looper) {            super(looper);        }        @Override        public void handleMessage(Message msg) {            onHandleIntent((Intent)msg.obj);            stopSelf(msg.arg1);        }    }

在Handler中我們處理完每一個命令都會調用stopSelf(int)方法來停止服務:該方法需要來自onStartCommand方法中的啟動ID,只有在接收到最新的啟動ID時才會停止服務,就是說,我們的IntentService直到命令隊列中的所有命令被執行完後才會停止服務。

setIntentRedelivery方法

在源碼中我們可以發現,該方法改變了boolean變數mRedelivery的值,而mRedelivery得值關係到onStartCommand的返回變數:

@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {    onStart(intent, startId);    return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;}

可以看到,mRedelivery不同,會返回兩個不同的標誌START_REDELIVER_INTENT 和START_NOT_STICKY,那麼他們有什麼不同呢?
區別就在於如果系統在服務完成之前關閉它,則兩種類型就表現出不同了:

  • START_NOT_STICKY型服務會直接被關閉,而START_REDELIVER_INTENT 型服務會在可用資源不再吃緊的時候嘗試再次啟動服務。
  • 由此我們可以發現,當我們的操作不是十分重要的時候,我們可以選擇START_NOT_STICKY,這也是IntentService的預設選項,當我們認為操作十分重要時,則應該選擇START_REDELIVER_INTENT 型服務。
non-sticky服務和sticky服務

non-sticky服務會在自己認為任務完成時停止,若一個Service為non-sticky服務則應該在onStartCommand方法中返回START_REDELIVER_INTENT或START_NOT_STICKY標誌。
sticky服務會持續存在,直到外部組件調用Context.stopService方法。sticky服務返回標誌位START_STICKY。

注意:IntentService不應該處理長時間啟動並執行服務(如音樂播放),長時間啟動並執行服務應該由sticky服務完成。

Android開發--IntentService的用法,你錯過了什麼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.