HandlerThread簡介
HandlerThread繼承了Thread赴邻,它是一種可以使用Handler的Thread违崇,它的實(shí)現(xiàn)就是在run()方法中通過Looper.prepare()創(chuàng)建消息隊(duì)列寨蹋,并通過Looper.loop()開啟消息循環(huán)兴想。這樣在實(shí)際使用中就允許在HandlerThread中創(chuàng)建Handler了斩例。
由于HandlerThread的run()方法是一個(gè)無限循環(huán)吼具,因此當(dāng)明確不需要使用HandlerThread的時(shí)候可以通過Looper的quit()或quitSafely()來終止線程執(zhí)行僚纷。
使用Handler
通常我們會(huì)在主線程中創(chuàng)建Handler,在子線程中調(diào)用handler.post(runnable)傳遞消息到主線程的消息隊(duì)列中處理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());
}
};
運(yùn)行結(jié)果
HandlerThreadActivity: Thread id = 10383
HandlerThreadActivity: Thread id = 1
使用HandlerThread
先創(chuàng)建HandlerThread實(shí)例怖竭,在onCreate()方法中
handlerThread = new HandlerThread("handlerThread");
handlerThread.start();
這樣就開啟了一個(gè)帶Looper的子線程,因?yàn)镠andlerThread是繼承自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ù)探索》中的消息機(jī)制,我的理解是:
- Looper.prepare();創(chuàng)建Looper實(shí)例
- Looper.loop();進(jìn)入一個(gè)無限循環(huán)中毅整,不斷監(jiān)聽消息隊(duì)列中是否有消息趣兄,有則把他取出來分發(fā)給handler的handlerMessage()中處理。
因?yàn)榫€程中需要有一個(gè)Looper悼嫉,線程綁定的handler才可以發(fā)送消息到消息隊(duì)列中艇潭,那么相應(yīng)的線程才會(huì)得到處理。
然后就是利用handlerThread獲取到Looper用來創(chuàng)建Handler實(shí)例
handler = new Handler(handlerThread.getLooper());
此時(shí)這個(gè)handler即使實(shí)在主線程中創(chuàng)建,但是它與子線程的Looper關(guān)聯(lián)了蹋凝,所以處理消息時(shí)候也會(huì)在子線程中處理的
btn_post_to_sub_thread.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.post(runnable);
}
});
運(yùn)行結(jié)果:
HandlerThreadActivity: Thread id = 10382
HandlerThreadActivity: Thread id = 10382
HandlerThreadActivity: Thread id = 10382
可以知道是在子線程中處理的鲁纠。
HandlerThread和Thread的區(qū)別
- 普通Thread主要用于在run()方法中執(zhí)行一個(gè)耗時(shí)的任務(wù)
- HandlerThread內(nèi)部創(chuàng)建消息隊(duì)列,需要handler消息方式來通知HandlerThread去執(zhí)行一個(gè)具體的任務(wù)鳍寂。