Android IntentService 源碼解析

前言

顧名思義,是一個(gè) Service,先說(shuō)和普通的 Service 的區(qū)別吧,普通的 Service 通常運(yùn)行在主線(xiàn)程,而 IntentService 的處理邏輯在子線(xiàn)程里,另外 Service 需要自己去 destroy,而 IntentService 在處理完自己的邏輯時(shí)會(huì)自動(dòng)結(jié)束,那他是怎么實(shí)現(xiàn)線(xiàn)程切換,主要還是 Handler 機(jī)制,內(nèi)部有一個(gè) HandleThread,關(guān)于這個(gè),可以查看 [HandlerThread 源碼解析] (http://www.itdecent.cn/p/5ff83236c8e2)

前世今生

public abstract class IntentService extends Service {}

繼承自 Service,擁有 Service 的特性,不熟悉 Service 的同學(xué)可以自行百度,面試必問(wèn)的,然而感覺(jué)我還是不想深入了解,以后再說(shuō)吧
記住

onCreate -> onStartCommand -> onDestroy
onCreate -> onBind -> onUnbind

自己寫(xiě)一個(gè) IntentService

public class MyIntentService extends IntentService {}

源碼解析

很熟悉的 Looper 和 ServiceHandler

    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

    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);
        }
    }

看一下 onCreate,初始化了一個(gè) HandlerThread,然后再把他的 Looper 拿出來(lái),然后拋棄了它,這個(gè) Looper 是子線(xiàn)程的 Looper,因此事件處理也發(fā)生在子線(xiàn)程。利用這個(gè) Looper 新建了一個(gè) Handler

  @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);
    }

啟動(dòng)以后調(diào)用 onStart,發(fā)送一個(gè)消息,onHandleIntent((Intent)msg.obj) 里面進(jìn)行處理,我們要重寫(xiě)這個(gè)方法,通常這個(gè)在子線(xiàn)程中運(yùn)行

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

   @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

處理完即關(guān)閉,不需要手動(dòng)關(guān)閉

    public final void stopSelf() {
        stopSelf(-1);
    }

    /**
     * Old version of {@link #stopSelfResult} that doesn't return a result.
     *  
     * @see #stopSelfResult
     */
    public final void stopSelf(int startId) {
        if (mActivityManager == null) {
            return;
        }
        try {
            mActivityManager.stopServiceToken(
                    new ComponentName(this, mClassName), mToken, startId);
        } catch (RemoteException ex) {
        }
    }

在我們自己的 IntentService 里面,寫(xiě)處理的邏輯,由于是在子線(xiàn)程中,所以可以處理耗時(shí)的邏輯,不必?fù)?dān)心 ANR,普通 Service 由于在主線(xiàn)程運(yùn)行,所以不能直接處理耗時(shí)邏輯

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            if (ACTION_FOO.equals(action)) {
                final String param1 = intent.getStringExtra(EXTRA_PARAM1);
                final String param2 = intenonHt.getStringExtra(EXTRA_PARAM2);
                handleActionFoo(param1, param2);
            } else if (ACTION_BAZ.equals(action)) {
                final String param1 = intent.getStringExtra(EXTRA_PARAM1);
                final String param2 = intent.getStringExtra(EXTRA_PARAM2);
                handleActionBaz(param1, param2);
            }
        }
    }

小結(jié)

非常簡(jiǎn)單的 IntentService,使用的時(shí)候注意與普通 Service 的區(qū)別即可,里面使用了 HandlerThread 獲取 Looper 對(duì)象,處理完會(huì)自動(dòng)關(guān)閉,即調(diào)用 onDestroy,再次啟動(dòng)又重新走 Service 的生命周期,一個(gè)問(wèn)題,如果多次 startService,那么 onHandleIntent 是怎么樣的呢?答案是一次執(zhí)行,因?yàn)?Looper 事件處理是阻塞的

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容