HandlerThread簡介
HandlerThread繼承了Thread,它是一種可以使用Handler的Thread,它的實現(xiàn)就是在run()方法中通過Looper.prepare()創(chuàng)建消息隊列,并通過Looper.loop()開啟消息循環(huán)。這樣在實際使用中就允許在HandlerThread中創(chuàng)建Handler了。
由于HandlerThread的run()方法是一個無限循環(huán),因此當(dāng)明確不需要使用HandlerThread的時候可以通過Looper的quit()或quitSafely()來終止線程執(zhí)行。
使用Handler
通常我們會在主線程中創(chuàng)建Handler,在子線程中調(diào)用handler.post(runnable)傳遞消息到主線程的消息隊列中處理runnable的run方法.這樣完成了子線程到主線的切換。
在onCreate()方法中
mainHandler = new Handler();
然后在子線程中post
btn_post_to_main_thread.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "Thread id = " + Thread.currentThread().getId());
mainHandler.post(runnable);
}
}).start();
}
});
runnable
private Runnable runnable = new Runnable() {
@Override
public void run() {
Log.d(TAG, "Thread id = " + Thread.currentThread().getId());
}
};
運行結(jié)果
HandlerThreadActivity: Thread id = 10383
HandlerThreadActivity: Thread id = 1
使用HandlerThread
先創(chuàng)建HandlerThread實例,在onCreate()方法中
handlerThread = new HandlerThread("handlerThread");
handlerThread.start();
這樣就開啟了一個帶Looper的子線程,因為HandlerThread是繼承自Thread,它的run方法是這樣定義的
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
關(guān)于Looper原理,可以參考《Android開發(fā)藝術(shù)探索》中的消息機制,我的理解是:
- Looper.prepare();創(chuàng)建Looper實例
- Looper.loop();進入一個無限循環(huán)中,不斷監(jiān)聽消息隊列中是否有消息,有則把他取出來分發(fā)給handler的handlerMessage()中處理。
因為線程中需要有一個Looper,線程綁定的handler才可以發(fā)送消息到消息隊列中,那么相應(yīng)的線程才會得到處理。
然后就是利用handlerThread獲取到Looper用來創(chuàng)建Handler實例
handler = new Handler(handlerThread.getLooper());
此時這個handler即使實在主線程中創(chuàng)建,但是它與子線程的Looper關(guān)聯(lián)了,所以處理消息時候也會在子線程中處理的
btn_post_to_sub_thread.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.post(runnable);
}
});
運行結(jié)果:
HandlerThreadActivity: Thread id = 10382
HandlerThreadActivity: Thread id = 10382
HandlerThreadActivity: Thread id = 10382
可以知道是在子線程中處理的。
HandlerThread和Thread的區(qū)別
- 普通Thread主要用于在run()方法中執(zhí)行一個耗時的任務(wù)
- HandlerThread內(nèi)部創(chuàng)建消息隊列,需要handler消息方式來通知HandlerThread去執(zhí)行一個具體的任務(wù)。