Android源碼系列二:HandlerThread和IntentService源碼剖析

在分析了 Handler源碼 之後,我們緊接着加入了相關聯的 HandlerThreadIntentService 的源碼剖析。

HandlerThread

它是 Thread 的子類,並且自帶 Looper 光環

  1. 如何使用:
        // 創建 HandlerThread 對象
        val handlerThread = HandlerThread("mainActivity")
        handlerThread.start()
        // 獲取 HandlerThread 中的 Looper 對象
        val myLooper: Looper = handlerThread.looper
        val handler = object : Handler(myLooper) {
            override fun handleMessage(msg: Message?) {
                // 運行在 HandlerThread 線程中
                super.handleMessage(msg)
                Log.d("taonce", "handleMessage thread is: ${Thread.currentThread().name}")
                Log.d("taonce", "handleMessage msg is: ${msg?.arg1}")
            }
        }
        val message: Message = handler.obtainMessage()
        message.arg1 = 0x11
        // 主線程中發送消息
        handler.sendMessage(message)
        thread {
            val msg: Message = handler.obtainMessage()
            msg.arg1 = 0x01
            // 子線程中發送消息
            handler.sendMessage(msg)
        }
        
    // Log:
    // handleMessage thread is: mainActivity
    // handleMessage msg is: 17
    // handleMessage thread is: mainActivity
    // handleMessage msg is: 1
    
    通過 Log 可以發現,無論我們在子線程中還是主線程中發送消息,handlerMessage(msg) 都是運行在 handlerThread 中。而且,將 handlerThread 中的 Looper 傳遞給 handler 後,handler 也不需要再進行 Looper.prepare()Looper.loop() 的執行過程了,最終 handlerhandleMessage(msg: Message?) 也會在 handlerThread 中進行。
    也就是說:HandlerThread 開啓了一個線程來實現多線程效果,但是它處理多任務是按照串行執行。
  2. 源碼簡析:
    @Override
    public void run() {
        mTid = Process.myTid(); 
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }
    
    源碼的 run() 方法中就是把我們在子線程中需要做的默認做了一遍,以免造成在子線程中使用 Handler.sendMessage(msg: Message?) 造成 No Looper 的異常。

IntentService

  1. 如何使用:

    class MyIntentService : IntentService("") {
        override fun onHandleIntent(intent: Intent?) {
        // 讓此線程休眠一會
         Thread.sleep(60 * 1000 * 1000)
        }
    
        override fun onStart(intent: Intent?, startId: Int) {
         super.onStart(intent, startId)
      }
    
        override fun onCreate() {
            super.onCreate()
     }
    }
    

    在我們使用 Service 的時候,都知道 Service 是運行在主線程中,不可以做耗時操作,但是我們在 IntentServiceonHandleIntent(intent: Intent?) 將線程休眠都沒有出現ANR,是不是很疑惑,下面我們就看看 IntentService 的源碼是怎麼處理的。

  2. 源碼簡析:

    // 我將一些未參與分析的源碼都給刪除了,只保留了和 HandlerThread 相關的
    public abstract class IntentService extends Service {
        // HandlerThread 中的 Looper 對象
        private volatile Looper mServiceLooper;
        // Handler 對象
        private volatile ServiceHandler mServiceHandler;
    
    
        private final class ServiceHandler extends Handler {
            public ServiceHandler(Looper looper) {
                super(looper);
            }
    
            @Override
            public void handleMessage(Message msg) {
                // 將子線程的處理交給抽象方法:onHandleIntent(@Nullable Intent intent)
                onHandleIntent((Intent)msg.obj);
                stopSelf(msg.arg1);
            }
        }
    
        @Override
        public void onCreate() {
    
            super.onCreate();
            // 創建 HandlerThread 對象,並開啓此線程
            HandlerThread thread = new HandlerThread("IntentService[" + mName +     "]");
            thread.start();
            // 獲取子線程中的 Looper 對象
            mServiceLooper = thread.getLooper();
            // 將 Looper 傳遞給 ServiceHandler
            mServiceHandler = new ServiceHandler(mServiceLooper);
        }
        
            @Override
        public void onStart(@Nullable Intent intent, int startId) {
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            // 發送消息,然後在 handleMessage(Message msg) 處理
            mServiceHandler.sendMessage(msg);
        }
        
        @WorkerThread
        protected abstract void onHandleIntent(@Nullable Intent intent);
    }
    

    IntentService 的源碼中,我們主要看三點:

    • mServiceLooper 變量,它是一個 Looper 對象
    • mServiceHandler 變量,它繼承了 Handler
    • threadonCreate() 方法中的局部變量,是一個 HandlerThread 變量

    我們開始一步一步分析:在 onCreate() 中,創建了 thread 變量,並且獲取到 looper ,傳遞給 mServiceHandler 對象,保證 serviceHandlerhandleMessage(Message msg) 在新開的線程中執行任務。

    onStart() 中,利用 mServiceHandler 發送一個 msg , 當 IntentService 執行到這的時候,mServiceHandler 就開始調用 handlerMessage(Message msg) ,我們看到在這裏面,源碼是直接調用了抽象方法 onHandlerIntent() 方法,這個方法會在我們自定義的 IntentService 中進行重寫,也就可以進行耗時操作了。

    HandlerThreadIntentService 的源碼在知曉 Handler 分發消息原理後很容易就理解,如果你在上面的分析中發現了不足或者認爲不正確的地方,歡迎留言指正或者掃描下方的二維碼聯繫我本人溝通交流,謝謝!

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