淺談 Android 消息運(yùn)行機(jī)制

? ? ? ?怕是要將Android面試常見(jiàn)的問(wèn)題講個(gè)遍雁仲。今天來(lái)分析分析Android 消息運(yùn)行機(jī)制沸久。



? ? ? ? Android 的消息運(yùn)行機(jī)制主要是指Handler的運(yùn)行機(jī)制炼幔。在日常開(kāi)發(fā)中淤井,Handler常用于更新UI等操作聊闯。那么為什么不可以在子線(xiàn)程中更新UI工猜?其實(shí)可以這樣理解,Android的UI是線(xiàn)程不安全菱蔬,如果我們多線(xiàn)程并發(fā)的更新UI篷帅,那么就會(huì)使得UI控件的值處于不可確定的狀態(tài),此時(shí)就會(huì)導(dǎo)致UI顯示結(jié)果并不是自己所預(yù)想的拴泌,如果我們對(duì)UI進(jìn)行加鎖呢魏身,我認(rèn)為加鎖首先會(huì)導(dǎo)致阻塞線(xiàn)程,降低UI的更新效率弛针,同時(shí)叠骑,我們加鎖后,可想此時(shí)UI的邏輯會(huì)變得很復(fù)雜削茁,此時(shí)我們就可以使用Handler來(lái)處理宙枷,會(huì)顯得更方便掉房。 線(xiàn)程是默認(rèn)沒(méi)有Looper的,而主線(xiàn)程再被創(chuàng)建時(shí)候就會(huì)初始化Looper慰丛,這就是主線(xiàn)程可以使用Handler原因卓囚。? ?

????????Handler的運(yùn)行則由Looper和MessageQueue來(lái)輔助完成。在我們創(chuàng)建Handler時(shí)候诅病,就會(huì)創(chuàng)建Looper對(duì)象和消息隊(duì)列MessageQueue及Handler哪亿,此時(shí)Handler,looper,MessageQueue就組成了消息的運(yùn)行機(jī)制。

? ? ? ? Handler整個(gè)的運(yùn)行是:Handler發(fā)送一個(gè)消息時(shí)贤笆,將消息放入MessageQueue的消息隊(duì)列中蝇棉,Looper發(fā)現(xiàn)消息時(shí)候,則會(huì)處理這條消息芥永,然后Handler的handleMessage的方法就會(huì)被調(diào)用篡殷。那么首先就開(kāi)始研究Looper:

? ? ? ??談到Looper時(shí),那么就會(huì)提到ThreadLocal,ThreadLocal 是什么呢埋涧?它是一個(gè)線(xiàn)程內(nèi)部的數(shù)據(jù)儲(chǔ)存類(lèi)板辽, Handler創(chuàng)建時(shí)候會(huì)采用當(dāng)前線(xiàn)程的Looper來(lái)構(gòu)建消息循環(huán)系統(tǒng),而獲取當(dāng)前的Lopper則通過(guò)ThreadLocal棘催,下文源碼可看出劲弦。下面通過(guò)源碼來(lái)分析和研究Looper:

? ? ? ?首先看看Looper的構(gòu)造方法,由下面源碼可以看出醇坝,此時(shí)我們創(chuàng)建Looper對(duì)象的時(shí)候邑跪,同時(shí)也創(chuàng)建了消息隊(duì)列MessageQueue ,并保存當(dāng)前線(xiàn)程的對(duì)象纲仍。

? ? 接下來(lái)就是Looper的初始化 :

? ? ? ?由上可以看出Looper創(chuàng)建是通過(guò)Looper.perpare()和prepareMainLooper()來(lái)創(chuàng)建的呀袱。其中prepareMainLooper從英文的注釋中我們可以看出此方法是給ActivityThread創(chuàng)建Looper使用贸毕,其本質(zhì)也是prepare 郑叠。創(chuàng)建消息隊(duì)列后,那么Looper就開(kāi)始自己的死循環(huán)工作了明棍,分析主要源碼如下圖:

? ? ? ? Looper的loop方法就是一個(gè)死循環(huán)乡革,其中退出這個(gè)死循環(huán)的方法是msg為空的時(shí)候(后面分析)。在msg空上面摊腋,還有一個(gè)方法MessageQueue的next方法沸版,接下來(lái)看看MessageQueue的next方法:

? ? ? ?此時(shí),next里面又是一個(gè)死循環(huán)兴蒸。MessageQueue中有個(gè)阻塞機(jī)制视粮,如上圈圈部分,那么是什么使得阻塞呢橙凳?接下來(lái)看看阻塞的觸發(fā)條件蕾殴,如下圖(接上源碼)笑撞,源碼很簡(jiǎn)單,當(dāng)消息隊(duì)列中沒(méi)有消息時(shí)候钓觉,此時(shí)將nextPollTimeoutMillis設(shè)置為-1茴肥,此時(shí)阻塞再next方法中,直到有消息來(lái)臨的時(shí)候荡灾。

? ? ? ? ? ?那么怎么跳出這個(gè)Looper呢瓤狐。Looper中提供了Quit方法如下,直接調(diào)用quit方法即可跳出當(dāng)前l(fā)ooper批幌,

? ? ? ? ?我們繼續(xù)看看到底是怎么跳出當(dāng)前Looper础锐,進(jìn)一步看看,此時(shí)可以看出荧缘,此時(shí)是將消息制空郁稍,正好對(duì)應(yīng)上面的msg為空的時(shí)候。(怎么處理Handler泄露問(wèn)題就不分析了胜宇,哈哈)

? ? ? ? 那么接下來(lái)耀怜,有消息的時(shí)候消息的分發(fā)處理。如下桐愉,可以看出财破,Handler發(fā)送消息過(guò)程,僅僅是向消息隊(duì)列中插入一條消息从诲,MessageQueue的next 將這條消息返回給Looper左痢,Looper接到消息開(kāi)始處理,最終交給Handler處理系洛,然后觸發(fā)Handler的 dispatchMessage俊性,源碼很簡(jiǎn)單,我們可以看出消息的處理了描扯。

? ? ? ? 以上Android消息運(yùn)行機(jī)制就講完了定页,畫(huà)個(gè)圖,算了绽诚,畫(huà)圖不是我所愛(ài)典徊。

? ? ? ?由于水平有限,如有不對(duì)恩够,歡迎指正卒落。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蜂桶,隨后出現(xiàn)的幾起案子儡毕,更是在濱河造成了極大的恐慌,老刑警劉巖扑媚,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腰湾,死亡現(xiàn)場(chǎng)離奇詭異贾费,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)檐盟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)褂萧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人葵萎,你說(shuō)我怎么就攤上這事导犹。” “怎么了羡忘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵谎痢,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我卷雕,道長(zhǎng)节猿,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任漫雕,我火速辦了婚禮滨嘱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘浸间。我一直安慰自己太雨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布魁蒜。 她就那樣靜靜地躺著囊扳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兜看。 梳的紋絲不亂的頭發(fā)上锥咸,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音细移,去河邊找鬼搏予。 笑死,一個(gè)胖子當(dāng)著我的面吹牛葫哗,可吹牛的內(nèi)容都是我干的缔刹。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼劣针,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了亿扁?” 一聲冷哼從身側(cè)響起捺典,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎从祝,沒(méi)想到半個(gè)月后襟己,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體引谜,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年擎浴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了员咽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贮预,死狀恐怖贝室,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仿吞,我是刑警寧澤滑频,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站唤冈,受9級(jí)特大地震影響峡迷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜你虹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一绘搞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧傅物,春花似錦看杭、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至尖阔,卻和暖如春贮缅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背介却。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工谴供, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人齿坷。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓桂肌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親永淌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子崎场,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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