談?wù)?android Handler機(jī)制--標(biāo)準(zhǔn)答案

最詳細(xì)的講解:
http://www.lxweimin.com/p/e172a2d58905
http://www.lxweimin.com/p/b4d745c7ff7a

handler機(jī)制涉及到的類有Looper,Handler,MessageQueue和Message。
一句話概括,Looper不斷獲取MessageQueue中的Message,交給Handler處理,同時(shí)Handler還向MessageQueue中投遞Message。

1.Handler
首先Handler與線程Thread是一對(duì)多的關(guān)系,因?yàn)槊總€(gè)Thread只對(duì)應(yīng)一個(gè)Looper,每個(gè)Looper只對(duì)應(yīng)一個(gè)MessageQueue,每個(gè)MQ中有多個(gè)Message,每個(gè)Message最多指定一個(gè)Handler處理。Handler有兩個(gè)作用,一是處理Message,二是將某個(gè)Message壓入MQ中。
實(shí)現(xiàn)第一個(gè)作用的方法是dispatchMessage和handleMessage. Looper從MQ中取出一個(gè)Message后,先調(diào)用Handler.dispatchMessage進(jìn)行分發(fā),流程是如果Message.callback不是空,執(zhí)行該callback;如果Handler.callback不是空,執(zhí)行該callback;如果前面的callback都不存在,調(diào)用Handler.handleMessage.
實(shí)現(xiàn)第二個(gè)作用的方法是send系列方法和post系列方法. send系列需要的參數(shù)是一個(gè)Message,post需要的參數(shù)是Runnable,本質(zhì)上是把Runnable設(shè)置為一個(gè)Message的callback,再壓入MQ。

2.MessageQueue
MessageQueue是一個(gè)隊(duì)列,有入隊(duì)出隊(duì),新增和銷毀等方法。

3.Looper
程序中的Looper有兩種情況,主線程的Looper和普通線程的Looper。它的使用都有3個(gè)步驟:1.Looper.prepare;2.創(chuàng)建處理消息的Handler;3.Looper.loop() .
prepare方法中會(huì)在當(dāng)前線程的ThreadLocal中保存一份Looper。ThreadLocal是一種線程內(nèi)的全局變量,不同線程中的ThreadLocal相互獨(dú)立無(wú)法訪問。Handler的構(gòu)造方法會(huì)獲取當(dāng)前線程的Looper,同時(shí)保存Looper的MQ
這樣四個(gè)對(duì)象就串起來(lái)了

其他知識(shí)點(diǎn)

https://www.cnblogs.com/muouren/p/11706454.html
https://blog.csdn.net/asdgbc/article/details/79148180

Handler 同步屏障 和 異步消息

  • Handler中的Message可以分為兩類:同步消息、異步消息,一般情況下這兩種消息的處理方式?jīng)]什么區(qū)別,只有在設(shè)置了同步屏障時(shí)才會(huì)出現(xiàn)差異。

  • 從代碼層面上來(lái)講,同步屏障就是一個(gè)Message,一個(gè)target字段為空的Message。
    設(shè)置了同步屏障之后,Handler只會(huì)處理異步消息。再換句話說(shuō),同步屏障為Handler消息機(jī)制增加了一種簡(jiǎn)單的優(yōu)先級(jí)機(jī)制,異步消息的優(yōu)先級(jí)要高于同步消息。

  • 如何使用異步消息?
    異步消息是不能使用的,因?yàn)橄嚓P(guān)設(shè)置都是hide。
    handler的相關(guān)構(gòu)造函數(shù),hide
    Mesasge.setAsynchronous(boolean),hide

IdleHandler

SyncBarrier(同步障礙器)與IdleHandler(閑時(shí)任務(wù))機(jī)制都是通過(guò) MQ 的 next() 方法提供的,
執(zhí)行IdleHandler其實(shí)就是調(diào)用其queueIdle()方法,queueIdle()如果返回false,next()方法會(huì)將該IdleHandler從mIdleHandlers中刪除。這樣的話,下一次next()方法再執(zhí)行IdleHandler時(shí)就不會(huì)再重復(fù)執(zhí)行它了。

Looper.prepare() 做了什么事情

new 一個(gè) Looper,然后保存在 ThreadLocal 中,和當(dāng)前線程綁定

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容