Handler機(jī)制中消息的創(chuàng)建、分發(fā)、處理、回收

系統(tǒng)handler 是在ActivityThread中定義的,變量名是mH(繼承了Handler)

該handler是系統(tǒng)Handler,會(huì)接收一些系統(tǒng)的消息,并處理之(如四大主件的生命周期的管理)。

Message(消息)

消息中不僅可以包含自定義的附加的arg1,arg2,obj,還可以綁定一個(gè)Runnable類(lèi)型的對(duì)象(Callback),注意,可以使用Handler的post方法直接回調(diào)該對(duì)象,注意,此時(shí)僅僅運(yùn)行了該Runnable的run方法,并不會(huì)啟動(dòng)新的線程。


temp.png

通常使用它來(lái)進(jìn)行一些循環(huán)類(lèi)的操作,如倒計(jì)時(shí)類(lèi)的輪播圖等。直接使用post開(kāi)始循環(huán),或者使用removeCallbacks(Runnable)很方便的取消循環(huán)。

消息的產(chǎn)生

Message在系統(tǒng)中是以消息池的形式管理的,消息池是用鏈表結(jié)構(gòu)實(shí)現(xiàn)的。每次從Message.obtain()獲取消息。
方法實(shí)現(xiàn)如下:


temp.png

發(fā)現(xiàn)鏈表第一個(gè)是用sPool(頭指針)來(lái)指向的,每次從鏈表取消息的時(shí)候,首先讓新msg從sPool來(lái)獲取,然后sPool移到鏈表下一個(gè)Message對(duì)象,新取出的Message初始化各種標(biāo)記,池子大小減一。

temp.png

消息的發(fā)送:

消息是由Handler的sendMessage方法發(fā)送到消息隊(duì)列中的,該方法有很多重載:

temp.png

其中的各種sendEmptyMessage其實(shí)內(nèi)部也會(huì)生成一個(gè)Message對(duì)象,只不過(guò)該對(duì)象沒(méi)有其他附加字段而已。


temp.png

可以看到有很多延遲的消息發(fā)送方法,也就說(shuō)消息不僅可以追加到隊(duì)列末尾,還可以插入到隊(duì)頭,所以消息發(fā)送到消息隊(duì)列時(shí)是可以”插隊(duì)”的,具體的“插隊(duì)”方法是由enqueueMessage(queue,msg,uptimeMillis)實(shí)現(xiàn)的。

消息的處理:

談到消息的處理過(guò)程就要從Looper的loop方法開(kāi)始看了,

temp.png

其中dispatchMessage方法實(shí)現(xiàn):

temp.png

從上圖我們看到我們通常復(fù)寫(xiě)的handler的handleMessage方法就是在dispatchMessage內(nèi)部調(diào)用的。

注意:loop循環(huán)中從消息隊(duì)列中取消息 queue.next() 其不一定是從隊(duì)列的頭部來(lái)取,還要看該消息有沒(méi)有設(shè)置延遲,如果該消息設(shè)置了延遲時(shí)間為0,那么立即取出該消息執(zhí)行,否則等待延遲時(shí)間到達(dá)后再取出執(zhí)行。(具體請(qǐng)參考next方法具體實(shí)現(xiàn)),此處也再次驗(yàn)證了前面“消息的發(fā)送”段落說(shuō)的消息是可以插隊(duì)的說(shuō)法。

消息的回收:

回收方法:

消息(Message)是循環(huán)使用的,上面介紹了消息的產(chǎn)生和處理,那么消息是如何回收的呢。其實(shí)具體的回收方法是在ActivityThread的recycle方法中進(jìn)行的,

temp.png

(在消息鏈表頭上加入一個(gè)元素)看到使用synchronized拿到池子,然后 讓next指向頭指針, 再讓剛剛加進(jìn)來(lái)的消息作為頭指針,然后池子消息數(shù)量加一。

回收時(shí)機(jī)

消息的回收是由系統(tǒng)進(jìn)行的,并不需要我們手動(dòng)回收,由于消息的產(chǎn)生和傳遞過(guò)程是:Message.obtain()-->msg.target.dispatchMessage(msg)-->msg.recycleUnchecked()(回收)。

從前面處理過(guò)程的圖片中可以看到回收是在我們已經(jīng)對(duì)消息處理完成之后進(jìn)行的(肯定得等消息處理完了再回收,要不還玩兒個(gè)毛線)。

總結(jié)

在消息泵Looper的作用下消息的整體流程如下:


temp.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 在Android開(kāi)發(fā)的多線程應(yīng)用場(chǎng)景中,Handler機(jī)制十分常用 今天,我將手把手帶你深入分析Handle...
    BrotherChen閱讀 534評(píng)論 0 0
  • 【Android Handler 消息機(jī)制】 前言 在Android開(kāi)發(fā)中,我們都知道不能在主線程中執(zhí)行耗時(shí)的任務(wù)...
    Rtia閱讀 5,098評(píng)論 1 28
  • Android是消息驅(qū)動(dòng)的,實(shí)現(xiàn)消息驅(qū)動(dòng)有幾個(gè)要素: 1、Message:消息,其中包含了消息ID,消息處理對(duì)象以...
    程序猿BOSS閱讀 893評(píng)論 0 1
  • 自己在練習(xí)的時(shí)候遇見(jiàn)了在cell中實(shí)現(xiàn)跳轉(zhuǎn),自己找資料問(wèn)同事,我知道的不只是這一種方法如:用代理的方法和塊對(duì)象,通...
    delegate閱讀 440評(píng)論 0 0
  • 眼角風(fēng)寒 一陣陣凝噎嗚咽 打轉(zhuǎn)的淚 亮晶晶 瘦弱的身軀 佝僂壓抑 煙囪的青絲縷縷 塵埃飛揚(yáng) 墻內(nèi)的高樓 撲棱棱速成...
    抱一閱讀 436評(píng)論 4 2

友情鏈接更多精彩內(nèi)容