HandlerThread以及IntentService的深入理解

HandlerThread以及IntentService的深入理解

一、HandlerThread

顧名思義:HandlerThread就是可以使用Handler的Thread
所在路徑:frameworks/base/core/java/android/os/HandlerThread.java
其run方法如下:

    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

其特殊之處在於:普通Thread在run方法中執行耗時任務,而HandlerThread在內部創建消息隊列,
外界需要通過Handler發送消息的方式,通知HandlerThread執行具體的任務。

二、IntentService

IntentService是一種特殊的Service,可用於執行後臺耗時任務。任務執行完它會自動停止,因爲其是服務的原因,其優先級是要遠高於其他線程。因爲它適合執行高優先級的後臺任務。
IntentService裏面封裝了HandlerThread和Handler,從它的onCreate方法中可以得知。

   public void onCreate() {
        super.onCreate();
        HandlerThread thread = 
                new HandlerThread("IntentService[" + mName + "]");
        thread.start();
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

利用HandlerThread的Looper來構建構建Handler,可得知Handler發送的消息最終會到HandlerThread執行。
每次啓動IntentService,它的onStartCommand都會被調用一次,它會在這個方法裏面處理外界發送過來的Intent,因爲onStartCommand裏面調用了onStart()函數,所以接下來看看onStart方法的實現:


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

可以得知,在這個方法裏面,只是通過ServiceHandler發送了一條信息。
接下來看看ServiceHandler的實現:

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

在這個函數中可以看到,ServiceHandler會對這個消息進行處理,其中這個Intent對象和外界的startService(intent)中的intent內容是完全一致,然後使用stopSelf(int startId)這個函數來停止服務(這個函數會等待所有的消息處理完畢後才終止服務),如果直接使用stopSelf()會立刻停止服務。
IntentService內部則通過消息的方式向HandlerThread請求執行任務,Handler中的Looper是順序處理消息的,這就意味着IntentService也是順序執行後臺任務的,當有多個後臺任務同時存在時,這些後臺任務會按照外界發起的順序排隊執行。
這裏附上IntentService的一個小實例:

    public class IntentServiceA extends IntentService {
        private static final String TAG = "LocalIntentService";
        public LocalIntentService() {
            super(TAG);
        }
        @Override
        protected void onHandleIntent(Intent intent) {
            String action = intent.getStringExtra("task_action");
            Log.d(TAG,"receive task :" + action);
            if ("com.ryg.action.TASK1".equals(action)) {
                Log.d(TAG,"handle task: " + action);
            }
        }
        @Override
        public void onDestroy() {
            Log.d(TAG,"service destroyed.");
            super.onDestroy();
        }
    }

在onHandleIntent方法中會從參數中解析出後臺任務的標識,即task_action字段所代表的內容,然後根據不同的任務標識來執行具體的後臺任務。

參考《Android開發藝術探索》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章