Handler源碼分析————實現Handler機制核心架構

此篇筆記用來記錄一下在網易公開課上學習的Handler源碼分析

在此之前本人對Handler的處理消息的機制架構也有一定的理解,但是還是沒有網易大佬啃的透徹,特此學習,十分感激

Handler:

Android SDK中用來處理異步消息的核心類,(像我們我的okhttp,retrofit,asyncTask等都是可以採用異步處理更新ui)

子線程可以通過Handler來更新ui

 

lopper輪循器

實際上looper和messageQueue的關係是是上圖,而第一個圖是爲了我們能夠更好的看明白handler和messageQueue和looper的關係

關鍵問題:1爲什麼handler能夠切換線程更新UI:這個問題比較深入,但是很簡單,

在Android的 入口類AcytivityThread中main方法中系統自動給我們創建了looper 如下

 

而我們main方法則在主線程中,so~ 我們的looper是自動在在主線程中的啦,然後再進行looper.loop方法取出發送到handerMessage中,而Handlermessage也是在主線程中的所以我們能夠在主線程中取到消息更新ui啦

 

2:整個消息隊列爲什麼只有一個messageQueue

源碼中每個隊列只有一個looper,他又只創建了一個MessageQueue    so~MessageQueus只有一個啦

 

1. Handler 的回調方法是在 Looper.loop()所調用的線程進行的;

2. Handler 的創建需要先調用 Looper.prepare() ,然後再手動調用 loop()方法開啓循環;

3. App 啓動時會在ActivityThread.main()方法中創建主線程的 Looper ,並開啓循環,所以主線程使用 Handler 不用調用第2點的邏輯;

4. 延時消息並不會阻塞消息隊列;

5. 異步消息不會馬上執行,插入隊列的方式跟同步消息一樣,唯一的區別是當有消息屏障時,異步消息可以繼續執行,同步消息則不行;

6. Callback.handleMessage() 的優先級比 Handler.handleMessage()要高*

7. Handler.post(Runnable)傳遞的 Runnale 對象並不會在新的線程執行;

8. Message 的創建推薦使用 Message.obtain() 來獲取,內部採用緩存消息池實現;

9. 不要在 handleMessage()中對消息進行異步處理;

10. 可以通過removeCallbacksAndMessages(null)或者靜態類加弱引用的方式防止內存泄漏;

11. Looper.loop()不會造成應用卡死,裏面使用了 Linux 的 epoll 機制。

說下 handler 機制,Looper 通過 MessageQueue 取消息,消息隊列是先進先出模式,那我延遲發兩個消息,第一個消息延遲2個小時,第二個消息延遲1個小時,那麼第二個消息需要等3個小時才能取到嗎?

回顧問題,我們來解答:

  • MessageQueue 的實現不是隊列,不要被名稱迷惑,他是一個鏈表

  • 每次發送消息都會按照 delay 從小到大進行重排

  • 所有的 delay 消息都是並行的,不是串行的

  • 第一個延遲2個小時,第二個延遲1小時,會優先執行第二個,再過1小時執行第一個           

  • MessageQueue 存消息的時候是使用當前時間進行排序的,有興趣的同學可以自己查看看源碼~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章