MessageQueue中的IdleHandler

在Android中,Handler是我們最常用的消息處理類,也是系統(tǒng)中非常重要的類,所以它的原理我們也應(yīng)該十分的清楚了解,所以Handler,Looper,MessageQueue成了我們必須學(xué)習(xí)和理解的東西,但是其中有一個接口很少被提及和使用,那就是IdleHandler。

IdleHandler

一、源碼解析

根據(jù)注釋我們很清楚的知道,這個接口方法是在消息隊列消息隊列全部處理完成后或者是在阻塞的過程中等待更多的消息的時候調(diào)用的,返回值絕對了處理一次后是否保存這個接口。雖然注釋很清楚,但是我們更多的應(yīng)該是要知道他是怎么處理的,所以看源碼:

先看下接口的添加和刪除:

添加接口
刪除接口

從上面所貼出的源碼中我們可以得到兩點(diǎn):

1、添加和刪除是線程安全的

2、通過查找可以得知mIdleHandlers是一個ArrayList,因此這個接口是可以重復(fù)添加的,不必?fù)?dān)心被替換問題

接下來我們看看接口是如何被調(diào)用的,通過源碼查找,我們知道了它是在next()方法中調(diào)用的,同時我們也知道,這個方法也是消息隊列用來循環(huán)消息的地方,由于方法比較長,我就只貼部分關(guān)鍵源碼:

其實(shí)這部分源碼注釋都已經(jīng)很清楚了

第一部分應(yīng)該算是條件判斷,首先判斷的是是不是第一次,pendingIdleHandlerCount的初始化為-1,其次判斷的是有沒有IdleHandler接口,如果沒有的話就是阻塞

第二部分是接口處理,主要是接口的調(diào)用以及判斷是不是接口只運(yùn)行一次就不需要了,最后是設(shè)置判斷的條件

二、系統(tǒng)源碼中的IdleHandler使用

通過上面的源碼分析可以找到,他是空閑時調(diào)用,這一定是一個非常有用的接口。于是在系統(tǒng)源碼中查找它的使用,發(fā)現(xiàn)了一點(diǎn)小小的驚喜,在這里分享給大家

在對源碼的學(xué)習(xí)中,我發(fā)現(xiàn)了IdleHandler的蹤跡,他出現(xiàn)的位置也是很關(guān)鍵的位置,在ActivityThread中,學(xué)習(xí)過源碼的同學(xué)都知道,這是一個非常重要的類,因?yàn)槠鋵?shí)這才算是一個程序的入口,額,有點(diǎn)遠(yuǎn)了,有興趣的同學(xué)可以自己去看下這個類,不多說,上源碼

上面的代碼很簡單,主要是添加和移除接口,以及接口實(shí)現(xiàn),但是接口實(shí)現(xiàn)的時候有個小驚喜啊,看方法名稱就很意外doGcIfNeeded(),這個地方涉及到回收。大家都知道系統(tǒng)會自動回收,但是什么時候回收,哪個地方回收的,一直都很模糊,現(xiàn)在總算知道一點(diǎn)了,但是這僅僅是一個方面的回收,不要當(dāng)成全部

回收

這個也很簡單了,主要是2次回收有最小時間間隔,就不多說了

Tips:

如果沒看過ActivityThread可能不知道上面的Looper.myQueue()指的是哪個Looper這里給大家說明下,還是先上源碼:

ActivityThread.java

使用過Looper的人應(yīng)該都很明白這個,從代碼中可以看出,這個地方準(zhǔn)備的是主線程,所以回收添加的Looper是MainLooper,另外大家不會忘了main方法吧:-D


三、其他源碼中的使用

請大家原諒我年輕,閱讀的開源代碼比較少,也可能是其他的開源項(xiàng)目中沒有這樣的需求,所以只在Glide中看到過這個接口的使用,Google不愧為最了解源碼的啊,源碼貼給大家

Engine.java

Glide是一個面向接口的開源項(xiàng)目,而且寫的很高明,本人的JAVA功底比較薄弱,所以看起來有點(diǎn)吃力,就不給大家具體解釋了,大家有興趣可以自己去查看,同時也希望有大神分析下Glide的源碼,膜拜。

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

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

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