在分析了 Handler源碼 之後,我們緊接着加入了相關聯的 HandlerThread
和 IntentService
的源碼剖析。
HandlerThread
它是 Thread
的子類,並且自帶 Looper
光環
- 如何使用:
通過// 創建 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()
的執行過程了,最終handler
的handleMessage(msg: Message?)
也會在handlerThread
中進行。
也就是說:HandlerThread
開啓了一個線程來實現多線程效果,但是它處理多任務是按照串行執行。 - 源碼簡析:
源碼的@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
-
如何使用:
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
是運行在主線程中,不可以做耗時操作,但是我們在IntentService
的onHandleIntent(intent: Intent?)
將線程休眠都沒有出現ANR,是不是很疑惑,下面我們就看看IntentService
的源碼是怎麼處理的。 -
源碼簡析:
// 我將一些未參與分析的源碼都給刪除了,只保留了和 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
-
thread
是onCreate()
方法中的局部變量,是一個HandlerThread
變量
我們開始一步一步分析:在
onCreate()
中,創建了thread
變量,並且獲取到looper
,傳遞給mServiceHandler
對象,保證serviceHandler
的handleMessage(Message msg)
在新開的線程中執行任務。在
onStart()
中,利用mServiceHandler
發送一個msg
, 當IntentService
執行到這的時候,mServiceHandler
就開始調用handlerMessage(Message msg)
,我們看到在這裏面,源碼是直接調用了抽象方法onHandlerIntent()
方法,這個方法會在我們自定義的IntentService
中進行重寫,也就可以進行耗時操作了。HandlerThread
和IntentService
的源碼在知曉Handler
分發消息原理後很容易就理解,如果你在上面的分析中發現了不足或者認爲不正確的地方,歡迎留言指正或者掃描下方的二維碼聯繫我本人溝通交流,謝謝!
-