IntentService介紹

1.IntentService 是什麼

  1. 一個封裝了HandlerThread和Handler的異步框架。
  2. 是一種特殊Service,繼承自Service,是抽象類,必須建立子類纔可使用。
  3. 可用於執行後臺耗時的任務,任務執行後會自動中止
  4. 具備高優先級(服務的緣由),優先級比單純的線程高不少,適合高優先級的後臺任務,且不容易被系統殺死。
  5. 啓動方式和Service同樣。
  6. 能夠屢次啓動,每一個耗時操做都會以工做隊列的方式在IntentService的onHandleIntent回調方法中執行。
  7. 串行執行。

 

2. IntentService的執行方式是串行仍是並行

  串行java

3. IntentService能夠執行大量的耗時操做?

  1. 若是隻有一個任務,是能夠進行耗時操做的。
  2. 若是有不少任務,因爲內部的HandlerThread是串行執行任務,會致使耗時操做阻塞了後續任務的執行。

4. IntentService和Service的區別

  1. 繼承自Service
  2. IntentService任務執行完後會自動中止
  3. IntentService和Service優先級一致,比Thread高。
  4. Service處於主線程不能直接進行耗時操做; IntentService內部有HandlerThread,能夠進行耗時操做。

 

5. IntentService的基本使用

1. 定義IntentService,實現onHandleIntent()'

public class LocalIntentService extends IntentService {
    public static final String TAG="LocalIntentService";
    public LocalIntentService( ) {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String task=intent.getStringExtra("task");
        Log.e(TAG, "onHandleIntent: task:"+task );
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "onCreate: " );
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy: " );
    }
}

  2.AndroidMainfest.xml 中聲明ItnentService

<service android:name=".LocalIntentService"/>

  3. 開啓IntentService

 findViewById(R.id.bt1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent service=new Intent(MainActivity.this,LocalIntentService.class);
                service.putExtra("task","task1");
                startService(service);

                service.putExtra("task","task2");
                startService(service);

                service.putExtra("task","task3");
                startService(service);

                service.putExtra("task","task4");
                startService(service);

            }
        });

  

日誌:

 

6. 源碼和原理機制

 1.IntetntService的OnCreate底層原理

  1. 構造了HandlerThread
  2. 並在每部保存了HandlerThread的Looper
  3. 而且使用該Looper建立了ServiceHandler
        //IntentService第一次啓動調用
        public void onCreate() {
            super.onCreate();
            //1. 建立一個HanlderThread
            HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
            thread.start();
            //2. 經過HanlderThread的Looper來構建Handler對象mServiceHandler
            mServiceLooper = thread.getLooper();
            mServiceHandler = new ServiceHandler(mServiceLooper);
        

2. IntentService的ServiceHandler

  1. HandlerThread會串行的取出任務而且執行,會調用ServiceHandler的handleMessage去處理任務。
  2. handlerMessage會去調用咱們自定義的onHandleIntent
  3. 任務執行完畢後經過stopSelf(startId)中止Service。
  4. 任務結束後,在onDestory()中會退出HandlerThread中Looper的循環。

  

        //ServiceHandler接收並處理onStart()方法中發送的Msg
        private final class ServiceHandler extends Handler {
            public ServiceHandler(Looper looper) {
                super(looper);
            }
            @Override
            public void handleMessage(Message msg) {
                //1. 直接在onHandleIntent中處理(由子類實現)
                onHandleIntent((Intent)msg.obj);
                /**=================================================
                 * 2. 嘗試中止服務(會等待全部消息都處理完畢後,纔會中止)
                 *   不能採用stopSelf()——會當即中止服務
                 *================================================*/
                stopSelf(msg.arg1); //會判斷啓動服務次數是否與startId相等
            }
        }

        public void onDestroy() {
            mServiceLooper.quit();
        }//銷燬時會中止looper

  

 

3. IntentService內部去中止Service爲何不直接採用stopSelf()

  1. 採用stopSelf()——會當即中止服務
  2. 採用stopSelf(startId),會等全部消息所有處理完畢後,纔會中止。會判斷啓動服務次數是否與startId相等

4. IntentService是如何中止HandlerThread的Looper消息循環的?

  1. 調用stopSelf(startId)後。
  2. 任務所有執行完,會中止服務,而且回調onDestory()。調用Looper的quit()方法便可

5. IntentService 屢次startService會屢次回調onHandleIntent()的內部流程?

  1. startService()->onStartCommand()->onStart()
  2. 經過HandlerThread的handler去發送消息。
  3. HandlerThread在處理任務時,會去調用onHandleIntent方法。

 

public abstract class IntentService extends Service {
        private volatile Looper mServiceLooper;
        private volatile ServiceHandler mServiceHandler;
        ...省略...

        //IntentService每次啓動都會調用
        public int onStartCommand(Intent intent, int flags, int startId) {
            //3. 直接調用onStart
            onStart(intent, startId);
            return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
        }
        public void onStart(Intent intent, int startId) {
            //4. 經過mServiceHandler發送一個消息(該消息會在HanlderThread中處理)
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            mServiceHandler.sendMessage(msg);
        }
        //2. 該Intent與startService(intent)中的Intent徹底一致
        protected abstract void onHandleIntent(Intent intent);

}

  

6. IntentService的源碼總結:

  1. IntentService經過發送消息的方式向HandlerThread請求執行任務
  2. HandlerThread中的looper是順序處理消息,所以有多個後臺任務時,都會按照外界發起的順序排隊執行
  3. 啓動流程:onCreate()->onStartCommand()->onStart()
  4. 消息處理流程:ServiceHandler.handleMessage()->onHandleIntent()

 

 

參考:

IntentService詳解

相關文章
相關標籤/搜索