IntentService源碼分析

我們帶着問題來看源碼!

一. 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);
}
  1. 獲得ServiceHandler消息的引用;
  2. 把Intent參數包裝到message的obj中發送消息,這裏的Intent = 啓動服務時StartService(Intent)傳入的Intent;
  3. 使用sendMessage()發送消息,即添加到消息隊列裏。此時的msg內攜帶了intent和startId。這裏就是最終需要調用的核心函數,源碼小夥伴自行查看。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章