Handler溃列,Looper面殖,ThreadLocal的工作原理

Handler執(zhí)行流程

首先handler作為任務執(zhí)行者,一般創(chuàng)建在主線程哭廉,當子線程有需要發(fā)送的數(shù)據(jù)脊僚,通過創(chuàng)建message對象,使用handler對象將消息發(fā)送到messagequeue遵绰,messagequeue遵循了隊列先進先出的原則辽幌,當主線程的looper循環(huán)消息的時候,會按照messagequeue隊列的順序循環(huán)消息椿访,并將消息給到任務執(zhí)行者handler去執(zhí)行任務乌企。

Handler的作用以及工作原理

作用:因為在Android中,主線程不建議做耗時的操作成玫,子線程不建議更新UI加酵,但是Android開發(fā),其實就是搭建好頁面哭当,將服務器的數(shù)據(jù)展示到頁面上猪腕,所以使用網(wǎng)絡請求會非常頻繁,而網(wǎng)絡請求屬于耗時操作钦勘,需要放到子線程完成陋葡,但一般情況下也不會通過子線程更新UI,需要將請求成功的數(shù)據(jù)發(fā)送到主線程進行UI更新彻采,所以一般會使用到handler腐缤。

下面再來說說工作原理

工作原理:Handler創(chuàng)建完成后,內(nèi)部的Looper以及MessageQueue就可以和Handler一起協(xié)同工作肛响,然后通過Hadler的post方法將一個Runnable投遞到Handler內(nèi)部的Looper中去處理岭粤,也可以通過Handler的send方法發(fā)送一個消息,這個消息會在Looper中做處理特笋。Post最終也是通過send來完成的剃浇。當Handler的send方法被調(diào)用時,他會調(diào)用MessageQueue的enqueueMessage方法將這個消息放入消息隊列中雹有,然后Looper發(fā)現(xiàn)有新消息到來時偿渡,就會處理這個消息,最終消息中的Runnable或者Handler的handlerMessage方法就會被調(diào)用霸奕。Looper是運行在Handler所在的線程溜宽,所以就把業(yè)務邏輯切換到主線程了。

ThreadLocal的工作原理

ThreadLocal的定義:ThreadLocal是線程內(nèi)部的數(shù)據(jù)存儲類质帅,通過他可以在指定的線程中存儲數(shù)據(jù)适揉,該數(shù)據(jù)只有在指定線程中可以獲取留攒。

ThreadLocal使用場景:當某些數(shù)據(jù)是以線程為作用域,并且不同線程具有不同的數(shù)據(jù)副本的時候嫉嘀;另外還可以使用在復雜邏輯下的對象傳遞炼邀。比如監(jiān)聽器的傳遞 ,
ThreadLoal的值在table數(shù)組中的存儲位置總是為ThreadLocal的reference字段所標識的對象的下一個位置剪侮。ThreasdLoacal的set和get方法所操作的對象都是當前線程的localValues對象的table數(shù)組拭宁,因此在不同的線程中訪問同一個ThreadLocal的set和get方法,他們對ThreadLocal所做的讀寫操作僅限于各自線程的內(nèi)部瓣俯,從而實現(xiàn)在多個線程中互不干擾的存儲和修改數(shù)據(jù)杰标。

Looper的工作原理

Looper在Android的消息機制中扮演著消息循環(huán)的角色,就是不停的從MessageQueue中查看是否有新消息彩匕,如果有消息就立刻處理腔剂,否則就一直阻塞在那里,首先在構(gòu)造方法中創(chuàng)建一個MessageQueue即隊列消息驼仪,然后將當前的對象保存起來掸犬。Looper除了prepare方法外,還提供了prepareMainLooper方法(這就是我們在MainActivity里并沒有聲明Lopper)绪爸,這個方法主要是給主線程也就是ActivityThread創(chuàng)建Looper使用的湾碎,其本質(zhì)也是通過prepare方法來實現(xiàn)的。由于主線程的Looper比較特殊毡泻,所以Looper提供了一個getMainLooper方法胜茧,通過它可以在任何地方獲取到主線程的Looper。

Looper的相關(guān)方法
Looper也是可以退出的仇味,Looper提供了quit和quitSafely來退出一個Looper,二者的區(qū)別是:quit會直接退出Looper雹顺,而quieSafely只是假定一個特殊標記丹墨,然后把消息隊列中的已有消息處理完畢后才安全退出。Looper退出后嬉愧,通過Handler發(fā)送消息失敗贩挣,這個時候Handler的send方法會返回false。在子線程中没酣,如果手動為其創(chuàng)建Looper王财,那么在所有的事情完成以后應該調(diào)用quit方法來終止消息循環(huán),否則這個子線程就會一直處于等待狀態(tài)裕便,而如果想退出Looper以后绒净,這個線程就會立刻終止,因此建議不需要的時候終止偿衰。Looper.loop()方法是個死循環(huán)挂疆,唯一跳出循環(huán)的方式是MessageQueue的next方法返回null改览。當Looper的quit方法被調(diào)用時,Looper就會調(diào)用MessageQueue的quit或者quitSafely方法來通知消息隊列退出缤言,當消息隊列被標記為退出狀態(tài)時宝当,它的next方法就返回null。Loop必須退出胆萧,否則loop循環(huán)就會無限循環(huán)下去庆揩。loop方法會調(diào)用MessageQueue的next方法,而next方法是一個當沒有消息時 跌穗,就是一個阻塞線程订晌,便會導致Looper也會阻塞在那里。
Looper傳值到Handler
當MessageQueue的next方法返回了新的消息瞻离,Looper就會處理這條消息:
(其實Looper就是通過這種方法把消息發(fā)給Handler)msg.target.disapatchMessage腾仅,這里msg.target是發(fā)送這條消息的Handler對象,消息交給dispatchMessage方法來處理套利。而這個dispatchMessage方法是在創(chuàng)建Handler時所用的Looper中執(zhí)行推励。這樣就把代碼邏輯切換到主線程。

當手動創(chuàng)建Looper時:
主線程向子線程發(fā)送消息:首先handler肯定是要創(chuàng)建到子線程當中肉迫,用于接收主線程發(fā)來消息進行處理验辞,但是,因為子線程沒有l(wèi)ooper對象喊衫,首先需要調(diào)用looper.prepare(),當主線程發(fā)來消息后跌造,已經(jīng)準備好的looper同樣會去消息隊列當中循環(huán)消息,交給handler族购,但handler真正能夠使用該數(shù)據(jù)還得調(diào)用looper.loop()開啟循環(huán);

歡迎各位大佬批評

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末壳贪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子寝杖,更是在濱河造成了極大的恐慌违施,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瑟幕,死亡現(xiàn)場離奇詭異磕蒲,居然都是意外死亡,警方通過查閱死者的電腦和手機只盹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門辣往,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人殖卑,你說我怎么就攤上這事站削。” “怎么了懦鼠?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵钻哩,是天一觀的道長屹堰。 經(jīng)常有香客問我,道長街氢,這世上最難降的妖魔是什么扯键? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮珊肃,結(jié)果婚禮上荣刑,老公的妹妹穿的比我還像新娘。我一直安慰自己伦乔,他們只是感情好厉亏,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著烈和,像睡著了一般爱只。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上招刹,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天恬试,我揣著相機與錄音,去河邊找鬼疯暑。 笑死训柴,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的妇拯。 我是一名探鬼主播幻馁,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼越锈!你這毒婦竟也來了仗嗦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤甘凭,失蹤者是張志新(化名)和其女友劉穎儒将,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體对蒲,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年贡翘,在試婚紗的時候發(fā)現(xiàn)自己被綠了蹈矮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡鸣驱,死狀恐怖泛鸟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踊东,我是刑警寧澤北滥,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布刚操,位于F島的核電站,受9級特大地震影響再芋,放射性物質(zhì)發(fā)生泄漏菊霜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一济赎、第九天 我趴在偏房一處隱蔽的房頂上張望鉴逞。 院中可真熱鬧,春花似錦司训、人聲如沸构捡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽勾徽。三九已至,卻和暖如春统扳,著一層夾襖步出監(jiān)牢的瞬間喘帚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工闪幽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留啥辨,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓盯腌,卻偏偏與公主長得像溉知,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子腕够,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

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