Handler

1. Handler 的前世今生

2. 為什么要Handler

  1. 子線程不能操作UI ,用Handler 從子線程切換到主線程
  2. 可以共用Handler 實(shí)現(xiàn)異步操作

3. Handler 是什么羽莺?

Handlerandroid 系統(tǒng)里面的一種消息處理機(jī)制

4. 如何使用Handler?

  1. 可以自己 new 一個(gè)Handler ,但是要注意 handler 導(dǎo)致的內(nèi)存泄漏
    ?把Handler 定義成一個(gè)靜態(tài)內(nèi)部類
    ?在Activity 或者fragment 關(guān)閉時(shí)移除 還沒(méi)有執(zhí)行的延時(shí)消息
  2. 通過(guò)任何一個(gè)view 是不是可以 getHandler,但是要注意 有可能為空蹂喻,比如 這個(gè)view 的 attacheInfo 為空意思就是這個(gè)view 還沒(méi)有 attach 到 window 上从媚。
  3. 還可以用過(guò) view 的 psot 方法催植。只要view 已經(jīng) attach 到window 上斑鸦,底層也是通過(guò)Handler 來(lái)實(shí)現(xiàn)的

5. Handler 消息種類窖贤?

  1. 同步消息
  2. 異步消息
  3. 屏障消息

6. Handler 如何發(fā)送消息砖顷?post 和 send 之間的區(qū)別

  1. 可以通過(guò)send 和post 兩種方式發(fā)送:
sendMessage(@NonNull Message msg)  
sendEmptyMessage(int what)
  
sendEmptyMessageAtTime(int what, long uptimeMillis)
sendEmptyMessageDelayed(int what, long delayMillis)
  
sendMessageDelayed(@NonNull Message msg, long delayMillis) 
sendMessageAtTime(@NonNull Message msg, long uptimeMillis) 
  
sendMessageAtFrontOfQueue(@NonNull Message msg)

  
post(@NonNull Runnable r)
  
postAtTime(@NonNull Runnable r, long uptimeMillis) 
// token 就相當(dāng)于給這個(gè) Message 打了一個(gè)標(biāo)簽,后期可以通過(guò) handler 的 removeCallbacksAndMessages 出入token 對(duì)消息進(jìn)行移除赃梧。
postAtTime(@NonNull Runnable r, @Nullable Object token, long uptimeMillis)
  
postDelayed(@NonNull Runnable r, long delayMillis)
postDelayed(Runnable r, int what, long delayMillis) // app 調(diào)用不了 
postDelayed(@NonNull Runnable r, @Nullable Object token, long delayMillis) 
  
postAtFrontOfQueue(@NonNull Runnable r) // 

上面的所有發(fā)送消息的方法(除sendMessageAtFrontOfQueue 以外)最終都會(huì)調(diào)用到handler 的 一個(gè) 叫 sendMessageAtTime(@NonNull Message msg, long uptimeMillis)滤蝠,在這個(gè)方法里面 調(diào)用enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,long uptimeMillis)把消息添加到消息隊(duì)列里面postAtFrontOfQueue(@NonNull Runnable r) 會(huì)調(diào)用 sendMessageAtFrontOfQueue 方法,在sendMessageAtFrontOfQueue 里面調(diào)用enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg, long uptimeMillis)

總的來(lái)說(shuō)就是 最終調(diào)用enqueueMessage 把消息入隊(duì)授嘀,這兒涉及到是三個(gè)參數(shù)物咳,
1: 隊(duì)列本身
2:消息本身
3:該消息執(zhí)行的準(zhǔn)確時(shí)間。
非延時(shí)消息:當(dāng)前系統(tǒng)時(shí)間
延時(shí)小時(shí):當(dāng)前系統(tǒng)時(shí)間+你要延時(shí)的時(shí)間
如果該消息是指明放在隊(duì)頭蹄皱,那么時(shí)間為0

面試如何回答:Handler 可以通過(guò)send 和 post 兩種方式發(fā)送消息览闰,這種兩種方式都可以發(fā)送即使消息,延時(shí)消息巷折,以及直接把消息發(fā)送到隊(duì)列的頭部压鉴,send 還可以發(fā)送空消息,但是不管通過(guò)哪種方handler 內(nèi)部都會(huì)封裝成一個(gè)Message 對(duì)象(如果是post 或者發(fā)的一個(gè)空消息)并且計(jì)算出消息執(zhí)行的確切時(shí)間锻拘,如果是即使消息晴弃,時(shí)間就是當(dāng)前系統(tǒng)時(shí)間,如果是延時(shí)消息就是當(dāng)前系統(tǒng)時(shí)間+延時(shí)的時(shí)間逊拍,如果是發(fā)送到隊(duì)列頭部時(shí)間就是0上鞠,之所以要計(jì)算時(shí)間就是因?yàn)槿腙?duì)的時(shí)候需要通過(guò)時(shí)間排序,最終調(diào)用一個(gè)叫enqueueMessage 的方法芯丧,在這個(gè)方法里面調(diào)用隊(duì)列自己的入隊(duì)方法芍阎,把消息本身和計(jì)算出來(lái)的時(shí)間傳遞進(jìn)去進(jìn)行入隊(duì)

7. Handler 消息如何入隊(duì)?如何排序缨恒?延時(shí)消息入隊(duì)機(jī)制谴咸?

8. Handler 消息如如何入隊(duì)和出隊(duì)?

  1. 入隊(duì):
    MessageQueue 實(shí)際上是一個(gè)鏈表的的結(jié)構(gòu)骗露,每一個(gè)Message 對(duì)象里面有一個(gè) next 變量用來(lái)指向它的下一個(gè)消息岭佳。Handler 只負(fù)責(zé)把消息交給MessageQueue,真正入隊(duì)的操作時(shí) 隊(duì)列自己完成的萧锉,隊(duì)列在對(duì)消息入隊(duì)時(shí)會(huì)更具消息執(zhí)行的時(shí)間進(jìn)行排序珊随,如果隊(duì)列是空 或者執(zhí)行時(shí)間為0 那么就排在頭部,如果頭部已經(jīng)有了,那么內(nèi)部有一個(gè)for 循環(huán) 叶洞,從頭部該是比較鲫凶,如果該消息執(zhí)行的時(shí)間小于頭部時(shí)間 ,那么就插入到頭部衩辟,然把自己的next 指向原來(lái)的頭部螟炫。如果消息執(zhí)行的時(shí)間大于頭部,那么就和后面的挨個(gè)比較艺晴,直到大于前面并且小于后面豹绪,那么就插入到他們中間揽思,如果比到最后一個(gè)幕庐,發(fā)現(xiàn)還是比最后一個(gè)大鹿寨,那么就插入到隊(duì)列最后一個(gè)却音。
    如果發(fā)送的消息進(jìn)過(guò)計(jì)算后會(huì) 插入入到頭部士败,如果發(fā)現(xiàn)主線程被阻塞了就會(huì)去喚醒述召,如果沒(méi)有則不喚醒心铃,入隊(duì)完成满着。
  2. 出隊(duì):
    從隊(duì)列的頭部開(kāi)始取谦炒,如果頭部有,用頭部消息執(zhí)行的時(shí)間和當(dāng)前系統(tǒng)時(shí)間進(jìn)行比較风喇,如果執(zhí)行時(shí)間小于 小于等于系統(tǒng)時(shí)間宁改,那么該消息滿足執(zhí)行條件,就通過(guò)消息找到Handler魂莫,然后調(diào)用Handler 的 dispatchMessage 方法把消息傳給了 Handler还蹲,最終調(diào)用handler 的 handleMessage 對(duì)消息進(jìn)行處理,如果不滿足耙考,那么用消息執(zhí)行的時(shí)間減去系統(tǒng)時(shí)間計(jì)算出需要等待的時(shí)間谜喊,然后阻塞在哪兒了,如果中途沒(méi)有其他人喚醒倦始,到了等待時(shí)間后會(huì)自動(dòng)被喚醒斗遏。

9. 為什么Handler 能把消息從子線程發(fā)送到主線程?

10. 如何在子線程中創(chuàng)建Handler?

11. 為什么UI 線程不會(huì)阻塞?

Handler

  1. 發(fā)送消息鞋邑,
  2. 處理消息
    Looper
    循環(huán)器诵次,循環(huán)從消息隊(duì)列里面取出消息,然后交給handler 處理
    Message
    消息的包裝類枚碗。里面可以用來(lái)傳遞數(shù)據(jù)
    MessageQueue
    消息隊(duì)列逾一,它是一個(gè)假的隊(duì)列,它本質(zhì)是一個(gè) 鏈表模擬的隊(duì)列
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肮雨,一起剝皮案震驚了整個(gè)濱河市遵堵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌怨规,老刑警劉巖鄙早,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汪茧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡限番,警方通過(guò)查閱死者的電腦和手機(jī)舱污,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)弥虐,“玉大人扩灯,你說(shuō)我怎么就攤上這事∷瘢” “怎么了珠插?”我有些...
    開(kāi)封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)颖对。 經(jīng)常有香客問(wèn)我捻撑,道長(zhǎng),這世上最難降的妖魔是什么缤底? 我笑而不...
    開(kāi)封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任顾患,我火速辦了婚禮,結(jié)果婚禮上个唧,老公的妹妹穿的比我還像新娘江解。我一直安慰自己,他們只是感情好徙歼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布犁河。 她就那樣靜靜地躺著,像睡著了一般魄梯。 火紅的嫁衣襯著肌膚如雪桨螺。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天酿秸,我揣著相機(jī)與錄音彭谁,去河邊找鬼。 笑死允扇,一個(gè)胖子當(dāng)著我的面吹牛缠局,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播考润,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼狭园,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了糊治?” 一聲冷哼從身側(cè)響起唱矛,我...
    開(kāi)封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后绎谦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體管闷,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年窃肠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了包个。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冤留,死狀恐怖碧囊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纤怒,我是刑警寧澤糯而,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站泊窘,受9級(jí)特大地震影響熄驼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜烘豹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一瓜贾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吴叶,春花似錦、人聲如沸序臂。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)奥秆。三九已至逊彭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間构订,已是汗流浹背侮叮。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悼瘾,地道東北人囊榜。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像亥宿,于是被迫代替她去往敵國(guó)和親卸勺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354