并發(fā)編程(7)Intentservice源碼分析

概述

前面分析了HandlerThread源碼,下面按照順序分析IntentService的源碼,IntentService是自己維護(hù)了一個線程,來執(zhí)行耗時的操作,然后里面封裝了HandlerThread,能夠方便在子線程創(chuàng)建Handler。

正文

注釋

IntentService is a base class for {@link Service}s that handle asynchronous
requests (expressed as {@link Intent}s) on demand.  Clients send requests
through {@link android.content.Context#startService(Intent)} calls; the
service is started as needed, handles each Intent in turn using a worker
thread, and stops itself when it runs out of work.

IntentService是繼承自Service用來處理異步請求的一個基類,客戶端startService發(fā)送請求,IntentService就被啟動,然后會在一個工作線程中處理傳遞過來的Intent,當(dāng)任務(wù)結(jié)束后就會自動停止服務(wù)。

This "work queue processor" pattern is commonly used to offload tasks
from an application's main thread.  The IntentService class exists to
simplify this pattern and take care of the mechanics.  To use it, extend
IntentService and implement {@link #onHandleIntent(Intent)}.  IntentService
will receive the Intents, launch a worker thread, and stop the service as appropriate

工作器處理模式通常用來加載應(yīng)用主線程的耗時任務(wù),IntentService用來簡化這種模式并且專注于耗時任務(wù)的處理。使用IntentService,需要繼承IntentService并且復(fù)寫onHandleIntent方法。IntentService在接收到一系列Intent之后,啟動一個子線程,然后合適的實際關(guān)閉Service。

All requests are handled on a single worker thread -- they may take as
  long as necessary (and will not block the application's main loop), but
  only one request will be processed at a time.

所有的請求都是都是在同一個子線程中進(jìn)行處理的—他們可能會花費很長時間(并不會阻塞應(yīng)用的loop線程),但是在同一時刻IntentService只能處理一個請求。

通過注釋,已經(jīng)將IntentService的使用方式,使用場景描述地相當(dāng)清楚,不再多解釋,相比較我們自己在Intent中開啟線程處理耗時任務(wù),IntentService不需要我們自己去關(guān)閉Service,它自己會在任務(wù)完成之后自行關(guān)閉,不過每次只能處理一個任務(wù),所以不適用于高并發(fā),適用于請求數(shù)較少的情況,類似于APP的版本檢測更新,后臺定位功能以及讀取少量的IO操作。

成員變量

    private volatile Looper mServiceLooper;//子線程中的Looper
    private volatile ServiceHandler mServiceHandler;//內(nèi)部持有的一個Handler
    private String mName;//內(nèi)部創(chuàng)建的線程名字
    private boolean mRedelivery;//服務(wù)被異常終止后重新創(chuàng)建調(diào)用onStartCommand是否回傳Intent

ServiceHandler

  private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
          //子線程中回調(diào)Intent
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }

內(nèi)部創(chuàng)建了一個ServiceHandler,然后將傳遞過來的Intent封裝成一個Message,然后再將Message封裝成一個Intent,回調(diào)onHandleIntent,其實轉(zhuǎn)換的目的就是講主線程的Intent切換到子線程中去執(zhí)行了而已。

構(gòu)造方法

  //工作線程的名字
  public IntentService(String name) {
        super();
        mName = name;
    }

onCreate

    @Override
    public void onCreate() {
        super.onCreate();
        //創(chuàng)建HandlerThread   
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        //開啟線程創(chuàng)建子線程Looper
        thread.start();
        //獲取子線程Looper
        mServiceLooper = thread.getLooper();
       //創(chuàng)建子線程Handler
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

onStartCommand

  @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        //調(diào)用onStart方法
        onStart(intent, startId);
       //根據(jù)mRedelivery的值來確定返回重傳Intent的黏性廣播還是非黏性廣播
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

onStart

  @Override
    public void onStart(@Nullable Intent intent, int startId) {
        //創(chuàng)建一個Message
        Message msg = mServiceHandler.obtainMessage();
        //消息標(biāo)志,作為當(dāng)前Service的標(biāo)志
        msg.arg1 = startId;
        //攜帶Intent
        msg.obj = intent;
        //發(fā)送消息,此時將線程切換到子線程
        mServiceHandler.sendMessage(msg);
    }


   @Override
        public void handleMessage(Message msg) {
            //處理發(fā)送過來的消息,在子線程
            onHandleIntent((Intent)msg.obj);
           //處理完消息之后停止Service
            stopSelf(msg.arg1);
        }

onDestroy

    @Override
    public void onDestroy() {
       //退出Looper
        mServiceLooper.quit();
    }

使用方式

IntentService intentService = new IntentService("main") {
    @Override
    protected void onHandleIntent(Intent intent) {
        // 處理耗時操作
    }
};
//不需要關(guān)注Service的生命周期,IntentService會自行處理

總結(jié)

IntentService實際上內(nèi)部實例化了一個HandlerThread,并且封裝了一個Handler,所以他的工作流程通過上面的源碼,分析如下:

  1. 創(chuàng)建一個HandlerThread,開啟HandlerThread來創(chuàng)建Looper
  2. 創(chuàng)建一個Handler,傳入Looper,從而在子線程實例化Handler
  3. 在onStartCommand中獲取到的Intent作為消息的obj發(fā)送出去
  4. 然后在onHandleIntent中處理這個消息,注意此時是在子線程
  5. 跟HandlerThread一樣,IntentService內(nèi)部是采用Handler來實現(xiàn)的,所以任務(wù)是串行執(zhí)行的,不適用于大量耗時操作。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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