Android handler 源碼解析理解

原理:

handler機(jī)制中包含4個(gè)關(guān)鍵類(下面對(duì)源碼的解析也是從這4個(gè)類入手)猫妙,Message(消息)歇终,MessageQueue(消息隊(duì)列)卤橄,Looper(輪詢器)乳附,Handler(消息發(fā)送和接收并處理)都毒,簡(jiǎn)單一句話概括就是:handler負(fù)責(zé)發(fā)送message色罚,將其加入到MessageQueue中,Looper不間斷的從MessageQueue中取出消息账劲,并發(fā)送給對(duì)應(yīng)的handler實(shí)例去處理戳护。

源碼理解:

我們經(jīng)常的使用handler是這樣的:

1、進(jìn)去源碼發(fā)現(xiàn)Hander是包含有Looper瀑焦,MessageQueue兩個(gè)比較重要的類腌且,handler 構(gòu)造器,調(diào)用下面的方法:

獲取looper對(duì)象:Looper.myLooper(); 進(jìn)去可以看到 返回了榛瓮,sThreadLocal.get();這個(gè)是什么玩意铺董?ThreadLocal,他是一個(gè)容器禀晓,里面封裝了一個(gè)map精续,以當(dāng)前線程的ThreadLocal作為key,以你要存的值作為value粹懒,我們這里value就是looper對(duì)象重付,這個(gè)容器是專門用來(lái)保存線程所特有的變量的,起到了線程間隔離的作用凫乖,如果有人想知道堪夭,我專門開一篇博客來(lái)講愕把。至于looper是怎么初始化的,客官莫急森爽,下面會(huì)講。

mQueue = mLooper.mQueue;拿到消息隊(duì)列嚣镜,這是一個(gè)鏈表結(jié)構(gòu)爬迟,注:一個(gè)線程對(duì)應(yīng)一個(gè)looper,一個(gè)looper同樣也只有一個(gè)queue菊匿;

callback這個(gè)是handler里面的一個(gè)接口付呕,在消息分發(fā)的時(shí)候會(huì)講到,默認(rèn)是null跌捆,mAsynchronous這個(gè)參數(shù)表示消息是否是異步消息徽职,默認(rèn)是false

2、再來(lái)看sendMessage佩厚,發(fā)送消息姆钉,:sendMessage ——> sendMessageDelayed ——>sendMessageAtTime

重點(diǎn):為什么msg要保存handler的引用呢?

我們都知道抄瓦,handler機(jī)制消息處理潮瓶,哪一個(gè)handler實(shí)例發(fā)出的消息,那么那一個(gè)handler就負(fù)責(zé)處理這個(gè)消息钙姊,這里的msg.target = this; 作用就在這毯辅,用來(lái)記住誰(shuí)將msg發(fā)出來(lái),等到處理的時(shí)候誰(shuí)就來(lái)處理煞额。

mMessages是即將要處理的message思恐,when越小,越要被有先處理膊毁。

3胀莹、重點(diǎn)又來(lái)了! Looper媚媒!

我們還是回到handler 初始化的時(shí)候嗜逻,我們是怎么獲取looper的,我們先看一個(gè)圖:


看上面的方法缭召,我們獲取Looper是從sThreadLocal獲取的栈顷。那我們就想它是何時(shí)set進(jìn)去的呢?我們想用looper嵌巷,就必須先prepare萄凤。

Looper是怎么初始化的呢,app中的通信搪哪,UI的刷新靡努,都需要依賴handler,那么,我們就猜想惑朦,Looper在app啟動(dòng)的時(shí)候就已經(jīng)開始創(chuàng)建并初始化了兽泄,那么我們?nèi)ピ创a中找 ActivityThread main()方法?


在主線程啟動(dòng)的時(shí)候就已經(jīng)啟動(dòng)了Looper并調(diào)用了,prepareMainLooper()和loop();接著去looper里面看看:


三個(gè)方法漾月,prepareMainLooper()其實(shí)內(nèi)部調(diào)用了prepare(false);這個(gè)boolean參數(shù)是什么意思呢病梢,意識(shí)就是不允許messageQueue退出,這個(gè)參數(shù)會(huì)在構(gòu)建Queue的時(shí)候傳遞進(jìn)去梁肿,因?yàn)橹骶€程的消息隊(duì)列只有在應(yīng)用退出的時(shí)候才允許退出蜓陌,否則······沒(méi)有否則,消息機(jī)制都沒(méi)了吩蔑,還怎么玩钮热!

prepare()方法創(chuàng)建了一個(gè)looper,但是looper并沒(méi)有啟動(dòng)烛芬,啟動(dòng)的方法是下面的loop();loop()有一個(gè)for(隧期;;),死循環(huán)蛀骇,里面做的工作就是一直取消息厌秒,并處理,然后recycleUnchecked()復(fù)用擅憔。這個(gè)時(shí)候looper就啟動(dòng)起來(lái)了鸵闪,只要你的應(yīng)用還在運(yùn)行,他就會(huì)一直在暑诸。looper拿到消息后會(huì)通過(guò)msg.target.dispatchMessage(msg); 將消息發(fā)出來(lái)給handler處理蚌讼,這里的msg.target不就是我們發(fā)消息的時(shí)候初始化的handler嗎?


判斷msg.callback是不是null个榕,如果不是篡石,那么就給這個(gè)callback處理,這個(gè)callback是message中的一個(gè)Runnable西采;Message.obtain()其實(shí)是有其他參數(shù)的方法的凰萨,其中有一個(gè)是obtain(Handler h, Runnable callback);如果你用了這個(gè)械馆,那么消息就會(huì)在你實(shí)現(xiàn)的Runnable中接收到處理的回調(diào)胖眷;

第二個(gè)是判斷handler內(nèi)部的callback是不是null,如果不是null霹崎,就讓他去處理珊搀,這里的Callback可不是Runnable了尾菇,他是一個(gè)interface境析,里面定義了一個(gè)handleMessage(Message msg);方法囚枪,這個(gè)怎么實(shí)現(xiàn)呢?handler類里同樣有Handler(Callback callback)構(gòu)造方法

最后才輪到handler類里的方法handleMessage來(lái)處理消息。也就是我們?cè)陂_始寫的那個(gè)簡(jiǎn)單的handler使用方法谒臼。



?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末趾徽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子湿颅,更是在濱河造成了極大的恐慌怕享,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猜拾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡全景,警方通過(guò)查閱死者的電腦和手機(jī)野崇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人忆肾,你說(shuō)我怎么就攤上這事×庑ぃ” “怎么了客冈?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)稳强。 經(jīng)常有香客問(wèn)我场仲,道長(zhǎng)和悦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任渠缕,我火速辦了婚禮鸽素,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘亦鳞。我一直安慰自己馍忽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布燕差。 她就那樣靜靜地躺著遭笋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪徒探。 梳的紋絲不亂的頭發(fā)上坐梯,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音刹帕,去河邊找鬼。 笑死谎替,一個(gè)胖子當(dāng)著我的面吹牛偷溺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钱贯,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼挫掏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了秩命?” 一聲冷哼從身側(cè)響起尉共,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弃锐,沒(méi)想到半個(gè)月后袄友,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡霹菊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年剧蚣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旋廷。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鸠按,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出饶碘,到底是詐尸還是另有隱情目尖,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布扎运,位于F島的核電站瑟曲,受9級(jí)特大地震影響饮戳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜测蹲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一莹捡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扣甲,春花似錦篮赢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至示辈,卻和暖如春寥茫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背矾麻。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工纱耻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人险耀。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓弄喘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親甩牺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蘑志,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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