Handler原始碼小窺

2021-07-30 22:21:33 字數 1476 閱讀 7496

最近在學著看原始碼,之前看原始碼,就是點進去直接看,看得很多卻毫無收穫,而且越看越模糊。受大佬教育啟發,看原始碼一定要帶著問題或者目的去看,才不會一團模糊,不懂得自己怎麼看了什麼。將具體的問題深入到原始碼中,結合原始碼進行分析,會印象深刻更有收穫

問題:1.handler如何傳送訊息

2.handler如何切換執行緒的?(如何使用handler進行執行緒間通訊?)

3.如何在子執行緒建立handler?

2.入口:

handler.sendmessage(new message());進入檢視**

sendmessageattime(),裡賦值了乙個messagequeue變數

發現未知型別 messagequeue,進入檢視構造方法,訊息佇列

往訊息佇列裡放入訊息,就沒有什麼觸發的**。

既然有放入訊息,就一定有取出的地方,看message壓入的**

q:如何取出 messagequeue中的訊息?

發現有乙個無限的for迴圈

是處理訊息佇列的壓入訊息的邏輯

發現messagequeue的mmessages是「佇列」的「主鍊子」容器

需要尋找主鍊子的提取(相當於提取主鍊子的「頭部」)

得知messagequeue只是處理message的鍊錶的邏輯**類

所以提取動作應該還在messagequeue尋找?

通常提取動作(肯定remove)

尋找remove關鍵字,看如何拆除message關係

mqueue 在何處賦值?mqueue = mlooper.mqueue;

發現未知型別 looper,進入looper中檢視

在構造方法中看到new 了乙個messagequeue和當前執行緒mthread

可以得知,looper類中就是存放messagequeue和當前執行緒的乙個容器

點進messagequeue檢視

new 乙個thread,在thread中new乙個handler

直接new 報錯

提示子執行緒在沒有呼叫loper.prepare()時,不可以new handler

在new handler前,增加loper.prepare()後再雲行

使用該handler傳送訊息,handlemessage沒法接收到訊息?

在後面加上looper.loop(),在執行,就可以收到訊息

why?

分析過程:

從loper.prepare()進入,發現未知型別 threadlocal

threadlocal是乙個用執行緒做key的鍵值對類

所以通過threadlocal就能判斷某條執行緒是否存在某條資訊

如果沒有某條執行緒中沒有值,則new looper作為值

new looper中,例項化messagequeue

handler的構造方法中,有looper和mq建立關係的**

經分析,looper的loop()方法是乙個無限迴圈從mq中取出訊息

將msg賦給了handler

Handler原始碼解析

意思就是說 在沒有呼叫looper.prepare 之前不能在子執行緒建立handler。為什麼在主線程中我們就已經可以直接建立handler?因為在activity的啟動 中,已經在當前ui執行緒 主線程 呼叫了looper.preparemainlooper 和looper.loop 方法。我們...

handler原始碼分析

昨天研究了一下handler的原始碼,今天總結一下 android只有乙個執行緒可以操作ui介面,我們稱之為ui執行緒。每個ui執行緒都維護乙個looper,這個looper中有乙個messagequeue來儲存ui乙個訊息佇列。通過控制這個訊息佇列來實現對ui介面的順序重新整理。handler.s...

Handler原始碼分析

當程式執行時,會先執行activitythread的main方法。會執行looper.preparemainlooper 方法和looper.loop 方法。looper.preparemainlooper public static void preparemainlooper smainloop...