1. HandlerThread的本質(zhì)
- 通過(guò)繼承
Thread類,創(chuàng)建一個(gè)帶有Looper對(duì)象的新工作線程,不需要手動(dòng)調(diào)用Looper.prepare()和Looper.loop()方法- 通過(guò)封裝
Handler類,快速創(chuàng)建handler并與其他線程進(jìn)行交互
我們首先將簡(jiǎn)單介紹Handler,然后應(yīng)用Handler+Thread來(lái)實(shí)現(xiàn)多線程通信,最后講解如何通過(guò)HandlerThread來(lái)實(shí)現(xiàn)多線程通信。
2. Handler
用于線程之間的通信,如將工作線程中需要更新UI的信息傳遞到主線程,從而實(shí)現(xiàn)
“工作線程對(duì)UI的更新”

Handler的工作流程
在這個(gè)過(guò)程中用到的組件有:Handler,Looper,MessageQueue,Message
-
Looper: 消息隊(duì)列和Handler的通信媒介,進(jìn)行消息循環(huán)- 消息獲取:循環(huán)取出消息隊(duì)列中的消息
-
消息分發(fā):將消息分發(fā)給對(duì)應(yīng)的
Handler,遵循“誰(shuí)發(fā)送,誰(shuí)處理”的原則
-
MessageQueue:- 一種數(shù)據(jù)結(jié)構(gòu),存儲(chǔ)
Handler發(fā)送過(guò)來(lái)的消息
- 一種數(shù)據(jù)結(jié)構(gòu),存儲(chǔ)
-
Message: 需要在某一線程執(zhí)行的操作信息-
obj為其攜帶的傳遞對(duì)象 -
what為消息標(biāo)識(shí)
-
-
整體流程:
-
Handler發(fā)送Msg,這個(gè)消息被存儲(chǔ)在該線程的MessageQueue,Looper不斷循環(huán)取出消息隊(duì)列中的Msg,并分發(fā)給對(duì)應(yīng)的Handler進(jìn)行處理。
-
- 一個(gè)線程會(huì)配備一個(gè)
Looper,一個(gè)MessageQueue, 但是可以擁有無(wú)數(shù)個(gè)Handler。 - 主線程中的
Looper已經(jīng)幫我們配置好了,所以我們并不需要自己實(shí)現(xiàn)Looper的相關(guān)操作,但是在其他線程如果想要使用Looper,需要自己進(jìn)行配置。 -
Handler會(huì)與線程進(jìn)行綁定,一個(gè)Handler只能與一個(gè)線程綁定(為這個(gè)線程發(fā)送和處理消息),但是一個(gè)線程可以與多個(gè)Handler進(jìn)行綁定
3. Handler + Thread 實(shí)現(xiàn)線程
3.1 sendMessage + handleMessage
- 在新建子線程中執(zhí)行耗時(shí)操作,并新建Message對(duì)象sendMessage
object: Thread(){
override fun run() {
try {
sleep(6000)
addDataToServiceList()
}catch (e: InterruptedException) {
e.printStackTrace()
}
val msg = Message.obtain()
msg.what = 1
handler.sendMessage(msg)
}
}.start()
- 在主線程中創(chuàng)建Handler對(duì)象,并handleMessage,根據(jù)Message的what屬性來(lái)確定操作
handler = object :Handler(){
override fun handleMessage(msg: Message) {
when(msg.what){
1-> setRecyclerView(mRecyclerView)
}
}
}
3.2 post
- 新建子線程,在執(zhí)行完try catch之后
- 執(zhí)行handler.post,在其中Runnable的run方法中執(zhí)行得到數(shù)據(jù)后的操作
handler = Handler()
object: Thread(){
override fun run() {
try {
sleep(6000)
addDataToServiceList()
}catch (e: InterruptedException) {
e.printStackTrace()
}
handler.post(Runnable {
setRecyclerView(mRecyclerView)
})
}
}.start()
4. HandlerThread
4.1 工作原理
- 通過(guò)繼承
Looper類,創(chuàng)建一個(gè)帶有Looper對(duì)象的新工作線程 - 通過(guò)封裝
Handler類,快速創(chuàng)建handler并與其他線程進(jìn)行交互
4.2 實(shí)現(xiàn)步驟
- 創(chuàng)建
HandlerThread實(shí)例對(duì)象:需要傳入一個(gè)線程名字的參數(shù),用來(lái)標(biāo)記該線程 - 因?yàn)?code>HandlerThread繼承了
Thread類,所以直接HandlerThread.start()就可以啟動(dòng)一個(gè)線程 - 創(chuàng)建
Handler并實(shí)現(xiàn)handleMessage方法 - 用
handler發(fā)送消息 - 結(jié)束線程:
HandlerThread.quit()
// 步驟1:創(chuàng)建HandlerThread實(shí)例對(duì)象
// 傳入?yún)?shù) = 線程名字,作用 = 標(biāo)記該線程
HandlerThread mHandlerThread = new HandlerThread("handlerThread");
// 步驟2:?jiǎn)?dòng)線程
mHandlerThread.start();
// 步驟3:創(chuàng)建工作線程Handler & 復(fù)寫(xiě)handleMessage()
// 作用:關(guān)聯(lián)HandlerThread的Looper對(duì)象、實(shí)現(xiàn)消息處理操作 & 與其他線程進(jìn)行通信
// 注:消息處理操作(HandlerMessage())的執(zhí)行線程 = mHandlerThread所創(chuàng)建的工作線程中執(zhí)行
Handler workHandler = new Handler( mHandlerThread.getLooper() ) {
@Override
public boolean handleMessage(Message msg) {
...//消息處理
return true;
}
});
// 步驟4:使用工作線程Handler向工作線程的消息隊(duì)列發(fā)送消息
// 在工作線程中,當(dāng)消息循環(huán)時(shí)取出對(duì)應(yīng)消息 & 在工作線程執(zhí)行相關(guān)操作
// a. 定義要發(fā)送的消息
Message msg = Message.obtain();
msg.what = 2; //消息的標(biāo)識(shí)
msg.obj = "B"; // 消息的存放
// b. 通過(guò)Handler發(fā)送消息到其綁定的消息隊(duì)列
workHandler.sendMessage(msg);
// 步驟5:結(jié)束線程,即停止線程的消息循環(huán)
mHandlerThread.quit();
5. 參考文檔
http://www.itdecent.cn/p/9c10beaa1c95
http://www.itdecent.cn/p/e172a2d58905
https://www.raywenderlich.com/5466-threading-with-handlerthread-in-android
https://blog.csdn.net/fdsafwagdagadg6576/article/details/110293636