IntentService 是Android為我們提供的一個類,繼承Service類,
第一步,先來看看源碼裡面開頭的注釋:
由上至少可以知道兩點:
1. IntentService 基于 類Service,用來處理異步請求。用戶端可以通過startService(Intent)來送出請求,該Service會在需要的時候建立,通過使用一個工作線程來處理請求,當所有的請求都處理完以後自動關閉;
2. 所有請求都單獨由一個工作線程進行處理。
第二步,我們看看IntentService的成員變量:
-
private volatile Looper mServiceLooper;
-
private volatile ServiceHandler mServiceHandler;
-
private String mName;
-
private boolean mRedelivery;
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);
-
}
-
}
在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中可以看出,如下:
-
final class ServiceRecord extends Binder {
-
...
-
private int lastStartId; // identifier of most recent start request.
-
...
-
public int getLastStartId() {
-
return lastStartId;
-
}
-
public int makeNextStartId() {
-
lastStartId++;
-
if (lastStartId < 1) {
-
lastStartId = 1;
-
}
-
return lastStartId;
-
}
-
...
-
}
由于這其中涉及Serivce建立和啟動的複雜過程,這裡隻是提一下,故本節不深入讨論
第三步,我們來看看幾個回調方法,我們知道Service建立時回調方法的調用順序為:onCreate -> onStartCommand -> onStart,是以我們先看onCreate(),實作如下:
-
@Override
-
public void onCreate() {
-
// TODO: It would be nice to have an option to hold a partial wakelock
-
// during processing, and to have a static startService(Context, Intent)
-
// method that would launch the service & hand off a wakelock.
-
super.onCreate();
-
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
-
thread.start();
-
mServiceLooper = thread.getLooper();
-
mServiceHandler = new ServiceHandler(mServiceLooper);
-
}
主要步驟如下:
1. 建立線程HandlerThread并啟動
2. 擷取線程的Looper,指派給mServiceLooper
3. 以該Looper對象做參數建立ServiceHandler
關于HandlerThread的分析可以參考:HandlerThread淺析
接着看onStartCommand()
-
@Override
-
public int onStartCommand(Intent intent, int flags, int startId) {
-
onStart(intent, startId);
-
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
-
}
這裡說明了不應該重載該方法,可以看到在該方法實作隻是簡單地調用了onStart(),把startService(Intent intent)傳遞過來的intent以及對應的startId傳遞給了onStart(), onStart()方法的實作如下:
-
@Override
-
public void onStart(Intent intent, int startId) {
-
Message msg = mServiceHandler.obtainMessage();
-
msg.arg1 = startId;
-
msg.obj = intent;
-
mServiceHandler.sendMessage(msg);
-
}
在onStart()方法裡,擷取和Servicehandler關聯的Message對象msg,并把intent指派給msg的obj,把startId指派給msg.arg1,然後發送msg,該Message會被MessageQueue接收,然後mServiceLooper會從該隊列中取出,交給ServiceHandler處理,這樣在就會執行前面介紹ServiceHandler的handleMessage(Message msg)方法。