我們帶着問題來看源碼!
一. IntentService如何單獨開啓一個新的工作線程?
@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();
// 1
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
// 2
mServiceLooper = thread.getLooper();
//3
mServiceHandler = new ServiceHandler(mServiceLooper);
}
1.實例化HandlerThread新建線程並啓動,這裏注意HandlerThread 繼承自Thread,內部封裝了Looper;
2. 獲得工作線程Looper,並維護自己的工作隊列;
3. 實例化ServiceHandler,並綁定獲取的Looper,這時屬於工作線程。
private final class ServiceHandler extends Handler {
// 1
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// 2
onHandleIntent((Intent)msg.obj);
// 3
stopSelf(msg.arg1);
}
}
1.構造函數;
2.在工作線程中,將message交給onHandleIntent()方法處理;
3.執行完調用stopSelf()結束服務。
@WorkerThread
// 1
protected abstract void onHandleIntent(@Nullable Intent intent);
1.onHandleIntent()抽象方法使用時需重寫
二. IntentService如何通過onStartCommand()將Intent傳遞給服務並依次插入到工作隊列中?
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
我們看下onStartCommand方法中的onStart()函數
@Override
public void onStart(@Nullable Intent intent, int startId) {
// 1
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
// 2
msg.obj = intent;
// 3
mServiceHandler.sendMessage(msg);
}
- 獲得ServiceHandler消息的引用;
- 把Intent參數包裝到message的obj中發送消息,這裏的Intent = 啓動服務時StartService(Intent)傳入的Intent;
- 使用sendMessage()發送消息,即添加到消息隊列裏。此時的msg內攜帶了intent和startId。這裏就是最終需要調用的核心函數,源碼小夥伴自行查看。