handler機(jī)制與原理

Handler機(jī)制

一.Handler 是什么?

Handler 主要是用于異步消息處理籍胯,類似于輔助類竟闪,他封裝了消息的投遞 處理的接口,通常用來(lái)處理耗時(shí)較長(zhǎng)的操作

二.Handler的原理:

handler中有四個(gè)重要的對(duì)象:


Looper 它的內(nèi)部包含了一個(gè)消息隊(duì)列,也就是Messagequeue 所有的handler發(fā)送的消息都會(huì)進(jìn)入這個(gè)消息隊(duì)列

Looper的loop方法 是一個(gè)死循環(huán)? 它不斷的從MessageQueue中來(lái)獲取消息 如果有消息就處理消息 沒(méi)有消息他就會(huì)進(jìn)去阻塞狀態(tài)

Meassagequeue 就是一個(gè)消息隊(duì)列 可以添加消息并處理消息

當(dāng)我們?cè)谥骶€程new一個(gè)Handler 的時(shí)候我們就可以使用主線程的Handler關(guān)聯(lián)到我們的looper和messagequeue當(dāng)我們難道數(shù)據(jù)以后我們用handlersendmesssage方法 用looper 這個(gè)循環(huán)去得到我們的數(shù)據(jù)

Activity的生命周期也是依賴handler的消息機(jī)制來(lái)進(jìn)行回調(diào)的 是在我們ActivityThread里handler 依靠 what 盡心分值 去進(jìn)行不同的回調(diào)方法杖狼,從而實(shí)現(xiàn)不同的Activity的生命周期炼蛤。handler 主要用于異步消息處理,Android提供給我們來(lái)更新UI的一套機(jī)制本刽,可以通過(guò)handler來(lái)發(fā)送消息鲸湃,也可以來(lái)接受并處理消息赠涮。

? 異步消息處理:? android 在設(shè)計(jì)時(shí)就分裝了這么一套機(jī)制,可以通過(guò)handler來(lái)發(fā)送消息暗挑,也可以接受并處理消息

如果不遵循這個(gè)機(jī)制就無(wú)法更新UI笋除,就會(huì)拋出異常。為什么要通過(guò)handler機(jī)制來(lái)跟新UI呢炸裆,因?yàn)榧僭O(shè)activity中有多個(gè)線程去更新ui ,并且沒(méi)有加鎖機(jī)制垃它,就會(huì)產(chǎn)生頁(yè)面亂,如果對(duì)ui操作進(jìn)行枷鎖機(jī)制的會(huì)性能會(huì)下降烹看,所以我們使用handler 保證消息處理的先后順序国拇。

由于Handler是運(yùn)行在主線程中(UI線程中),? 而且它的設(shè)計(jì)可以使它與子線程通過(guò)Message對(duì)象來(lái)傳遞數(shù)據(jù), 這個(gè)時(shí)候,Handler就承擔(dān)著接受子線程傳過(guò)來(lái)的(子線程用sedMessage()方法傳弟)Message對(duì)象惯殊,(里面包含數(shù)據(jù))? ,把這些消息放入主線程隊(duì)列中酱吝,配合主線程進(jìn)行更新UI。子線程對(duì)主線程發(fā)信息Message對(duì)象(Message包含的信息可以是int土思,object類型)盡可能使用Message.what來(lái)標(biāo)識(shí)信息务热,以便用不同的方式處理Message;

執(zhí)行流程: 子線程通過(guò)sendmessage發(fā)送message消息己儒,這個(gè)消息會(huì)被放入messageQueue隊(duì)列中崎岂,

隊(duì)列會(huì)以先進(jìn)先出的方式,被Looper抽取闪湾,looper抽取到信息冲甘,交由主線程的handler,handler通過(guò)handleMessage處理信息途样,之后更新ui江醇。

handler主要有

Message:消息,其中包含了消息ID何暇,消息處理對(duì)象以及處理的數(shù)據(jù)等嫁审,由MessageQueue統(tǒng)一列隊(duì),終由Handler處理赖晶。

Handler:處理者,負(fù)責(zé)Message的發(fā)送及處理辐烂。使用Handler時(shí)遏插,需要實(shí)現(xiàn)handleMessage(Message msg)方法來(lái)對(duì)特定的Message進(jìn)行處理,例如更新UI等纠修。

Handler類的主要作用:(有兩個(gè)主要作用)1)胳嘲、在工作線程中發(fā)送消息;2)扣草、在主線程中獲取了牛、并處理消息颜屠。

MessageQueue:消息隊(duì)列,用來(lái)存放Handler發(fā)送過(guò)來(lái)的消息鹰祸,

并按照FIFO規(guī)則執(zhí)行甫窟。當(dāng)然,存放Message并非實(shí)際意義的保存蛙婴,而是將Message串聯(lián)起來(lái)的粗井,等待Looper的抽取。

Looper:消息泵街图,不斷地從MessageQueue中抽取Message執(zhí)行浇衬。因此,一個(gè)MessageQueue需要一個(gè)Looper餐济。 默認(rèn)一個(gè)線程是不存在消息循環(huán)的耘擂,需要調(diào)用Looper.prepare來(lái)創(chuàng)建一個(gè)消息循環(huán),

調(diào)用Looper.loop來(lái)使消息循環(huán)起作用絮姆,當(dāng)調(diào)用完loop方法后循環(huán)開(kāi)始醉冤,從消息MessageQueue隊(duì)列中抽取消息,下一個(gè)由handler發(fā)送的message將會(huì)被這個(gè)handler的handleMessage處理滚朵。處理完成后調(diào)用Message.recycle將其放入Message pool中冤灾。

Thread:線程,負(fù)責(zé)調(diào)度整個(gè)消息循環(huán)辕近,即消息循環(huán)的執(zhí)行場(chǎng)所韵吨。

handler引起內(nèi)存泄漏的原因及解決方案

如果用戶在網(wǎng)絡(luò)請(qǐng)求過(guò)程中關(guān)閉了Activity,正常情況下移宅,Activity不再被使用归粉,在onDestory()方法中執(zhí)行GC檢查時(shí)就應(yīng)該被回收掉。

但由于這時(shí)線程尚未執(zhí)行完漏峰,而該線程持有Handler的引用(不然它怎么發(fā)消息給Handler糠悼?),

這個(gè)Handler又持有Activity的引用浅乔,就導(dǎo)致該Activity無(wú)法被回收倔喂,造成內(nèi)存泄漏,直到網(wǎng)絡(luò)請(qǐng)求結(jié)束(圖片下載完畢)靖苇。

如果你執(zhí)行了Handler的postDelayed()方法席噩,該方法會(huì)將你的Handler裝入一個(gè)Message,并把這條Message推到MessageQueue中贤壁,那么在你設(shè)定的delay到達(dá)之前悼枢,

會(huì)有一條MessageQueue -> Message -> Handler -> Activity的鏈,導(dǎo)致你的Activity被持有引用而無(wú)法被回收脾拆。

解決:靜態(tài)內(nèi)部類馒索,靜態(tài)內(nèi)部類不會(huì)被當(dāng)前這個(gè)類所引用莹妒,再使用弱引用,gc觸發(fā)時(shí)將handler中的activity回收绰上。

在關(guān)閉Activity的時(shí)候停掉你的后臺(tái)線程旨怠。線程停掉了,就相當(dāng)于切斷了Handler和外部連接的線渔期,Activity自然會(huì)在合適的時(shí)候被回收运吓。

如果你的Handler是被delay的Message持有了引用,那么使用相應(yīng)的Handler的removeCallbacks()方法疯趟,把消息對(duì)象從消息隊(duì)列移除就行了拘哨。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市信峻,隨后出現(xiàn)的幾起案子倦青,更是在濱河造成了極大的恐慌,老刑警劉巖盹舞,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件产镐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡踢步,警方通過(guò)查閱死者的電腦和手機(jī)癣亚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)获印,“玉大人述雾,你說(shuō)我怎么就攤上這事〖娣幔” “怎么了玻孟?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鳍征。 經(jīng)常有香客問(wèn)我黍翎,道長(zhǎng),這世上最難降的妖魔是什么艳丛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任匣掸,我火速辦了婚禮,結(jié)果婚禮上氮双,老公的妹妹穿的比我還像新娘旺聚。我一直安慰自己,他們只是感情好眶蕉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著唧躲,像睡著了一般造挽。 火紅的嫁衣襯著肌膚如雪碱璃。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天饭入,我揣著相機(jī)與錄音嵌器,去河邊找鬼。 笑死谐丢,一個(gè)胖子當(dāng)著我的面吹牛爽航,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乾忱,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼讥珍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了窄瘟?” 一聲冷哼從身側(cè)響起衷佃,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹄葱,沒(méi)想到半個(gè)月后氏义,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡图云,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年惯悠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竣况。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡克婶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出帕翻,到底是詐尸還是另有隱情鸠补,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布嘀掸,位于F島的核電站紫岩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏睬塌。R本人自食惡果不足惜泉蝌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望揩晴。 院中可真熱鬧勋陪,春花似錦、人聲如沸硫兰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)劫映。三九已至违孝,卻和暖如春刹前,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雌桑。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工喇喉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人校坑。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓拣技,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親耍目。 傳聞我的和親對(duì)象是個(gè)殘疾皇子膏斤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355