天天看點

IntentService 分析

IntentService 是Android為我們提供的一個類,繼承Service類,

第一步,先來看看源碼裡面開頭的注釋:

由上至少可以知道兩點:

1. IntentService 基于 類Service,用來處理異步請求。用戶端可以通過startService(Intent)來送出請求,該Service會在需要的時候建立,通過使用一個工作線程來處理請求,當所有的請求都處理完以後自動關閉;

2. 所有請求都單獨由一個工作線程進行處理。

第二步,我們看看IntentService的成員變量:

  1. private volatile Looper mServiceLooper;

  2. private volatile ServiceHandler mServiceHandler;

  3. private String mName;

  4. private boolean mRedelivery;

ServiceHandler是一個靜态内部類,代碼如下:

  1. private final class ServiceHandler extends Handler {

  2. public ServiceHandler(Looper looper) {

  3. super(looper);

  4. }

  5. @Override

  6. public void handleMessage(Message msg) {

  7. onHandleIntent((Intent)msg.obj);

  8. stopSelf(msg.arg1);

  9. }

  10. }

在handleMessage(Message msg)方法裡,會調用onHandleIntent(Intent intent)方法處理請求,這一步說明了我們在使用IntentService時為什麼得重載onHandleIntent(Intent intent)方法并在其中實作我們自己的處理;

接着,在處理完請求後就會調用stopSelf(int startId)嘗試停止自己,注意這裡調用的是stopSelf(int startId),而不是sotpSelf(),實際上stopSelf也是調用stopSelf(int startId),隻不過startId指定為-1,兩者的差別在于stopSelf(int startId)會等所有請求處理完才停止,而stopSelf()是直接停止。

其中startId的解釋如下:

// startId A unique integer representing this specific request to start
           

可以簡單了解startId記錄了該Service被啟動的次數,從1開始計算,每啟動一次自增1,從ServiceRecord中可以看出,如下:

  1. final class ServiceRecord extends Binder {

  2.         ...

  3.         private int lastStartId;     // identifier of most recent start request.

  4.         ...

  5.         public int getLastStartId() {

  6.             return lastStartId;

  7.         }

  8.         public int makeNextStartId() {

  9.             lastStartId++;

  10.             if (lastStartId < 1) {

  11.                 lastStartId = 1;

  12.             }

  13.             return lastStartId;

  14.        }

  15.         ...

  16. }

由于這其中涉及Serivce建立和啟動的複雜過程,這裡隻是提一下,故本節不深入讨論

第三步,我們來看看幾個回調方法,我們知道Service建立時回調方法的調用順序為:onCreate -> onStartCommand -> onStart,是以我們先看onCreate(),實作如下:

  1. @Override

  2. public void onCreate() {

  3. // TODO: It would be nice to have an option to hold a partial wakelock

  4. // during processing, and to have a static startService(Context, Intent)

  5. // method that would launch the service & hand off a wakelock.

  6. super.onCreate();

  7. HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");

  8. thread.start();

  9. mServiceLooper = thread.getLooper();

  10. mServiceHandler = new ServiceHandler(mServiceLooper);

  11. }

主要步驟如下:

1. 建立線程HandlerThread并啟動

2. 擷取線程的Looper,指派給mServiceLooper

3. 以該Looper對象做參數建立ServiceHandler

關于HandlerThread的分析可以參考:HandlerThread淺析

接着看onStartCommand()

  1. @Override

  2. public int onStartCommand(Intent intent, int flags, int startId) {

  3. onStart(intent, startId);

  4. return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;

  5. }

這裡說明了不應該重載該方法,可以看到在該方法實作隻是簡單地調用了onStart(),把startService(Intent intent)傳遞過來的intent以及對應的startId傳遞給了onStart(), onStart()方法的實作如下:

  1. @Override

  2. public void onStart(Intent intent, int startId) {

  3. Message msg = mServiceHandler.obtainMessage();

  4. msg.arg1 = startId;

  5. msg.obj = intent;

  6. mServiceHandler.sendMessage(msg);

  7. }

在onStart()方法裡,擷取和Servicehandler關聯的Message對象msg,并把intent指派給msg的obj,把startId指派給msg.arg1,然後發送msg,該Message會被MessageQueue接收,然後mServiceLooper會從該隊列中取出,交給ServiceHandler處理,這樣在就會執行前面介紹ServiceHandler的handleMessage(Message msg)方法。

繼續閱讀