# 讀 Android 開發藝術探索 &11

關鍵詞:消息機制 / Handler

本次筆記梳理了和 Android 的消息機制的知識點。Handler 是 Android 消息機制的上層接口,通過它可以輕鬆將一個任務切換到 Handler 所在的線程中去執行。Android 的消息機制主要是指 Handler 的運行機制,Handler 的運行需要底層的 MessageQueue 和 Looper 的支撐。

有時候需要在子線程中進行耗時的 I/O 操作,可能是讀取文件或者訪問網絡等,當耗時操作完成之後可能要在 UI 上做一些改變,由於 Android 開發規範的限制,我們並不能在子線程中訪問 UI 控件,否則就會觸發程序異常,這個時候通過 Handler 就可以將更新 UI 的操作切換到主線程中執行。(所以 Handler 常被開發者用來更新 UI)

1. Handler #

  1. 系統之所以提供 Handler,主要原因是爲了解決在子線程中無法訪問 UI 的矛盾;
  2. Handler 的主要作用就是將一個任務切換到某個指定的線程中去執行;
  3. 爲什麼不能在子線程中訪問 UI 呢?因爲 Android 的 UI 控件不是線程安全的;
  4. Handler 的工作主要包含消息的發送和接收過程,消息的發送可以通過 post 的一系列方法以及 send 的一系列方法來實現,post 的一系列方法最終是通過 send 的一系列方法來實現的;
  5. Handler 發送消息的過程僅僅是向消息隊列插入了一條消息,MessageQueue 的 next 方法就會返回這條消息給 Looper,Looper 收到消息後就開始處理了,最終消息由 Looper 交由 Handler 處理,即 Handler 的 dispatchMessage 方法會被調用,這時 Handler 就進入了處理消息的階段;

2. Looper 和 ThreadLocal #

  1. ThreadLocal 是 Looper 中的一個比較特殊的概念,它不是線程,作用是可以在每個線程中存儲數據;
  2. Handler 內部如何獲取當前線程的 Looper? 便是使用 ThreadLocal,ThreadLocal 可以在不同的線程中互不干擾地存儲並提供數據,通過 ThreadLocal 可以輕鬆獲取每個線程的 Looper;
  3. ThreadLocal 是一個線程內部的數據存儲類,通過它在指定的線程中存儲數據,數據存儲之後,只有在指定線程中可以獲取到存儲的數據,對於其他線程來說則無法獲取到數據;
  4. 一般來說,當某些數據是以線程爲作用域並且不同線程具有不同的數據副本的時候,可以考慮採用 ThreadLocal;
  5. ThreadLocal 的另一個使用場景是 複雜邏輯下的對象傳遞,比如監聽器的傳遞;採用 ThreadLocal 可以讓監聽器作爲線程內的全局對象而存在,在線程內部只要通過 get 方法就能獲取到監聽器;採用 ThreadLocal,每個監聽器對象都在自己的線程內部存儲;
  6. 不同線程中訪問的是同一個 ThreadLocal 對象,但是它們通過 ThreadLocal 獲取到的值確實不一樣的,這是 ThreadLocal 的奇妙之處;
  7. ThreadLocal 是一個泛型類 public class ThreadLocal<T>;

  8. Looper 扮演着消息循環的角色,不停的從 MessageQueue 中查看是否有新消息,如果有新消息就會立刻處理,否則會一直阻塞在那裏;

  9. Handler 的工作需要 Looper,沒有 Looper 的線程就會報錯;通過 Looper.prepare() 即可爲當前的線程創建一個 Looper,接着通過 Looper.loop() 來開啓消息循環;
  10. quit 會直接退出 Looper,而 quitSafely 只是設定一個退出標記;
  11. Looper 必須要有退出,否則 loop 方法就會無限循環下去

3. MessageQueue #

  1. 消息隊列主要包含兩個操作:插入 和 讀取;分別對應着方法:enqueueMessage 和 next
  2. 讀取操作本身會伴隨着刪除操作;
  3. MessageQueue 的內部實現並不是用的隊列,而是通過一個單鏈表的數據結構來維護消息列表,單鏈表在插入和刪除上比較有優勢;
  4. next 是一個無限循環的方法,如果消息隊列中沒有消息,next 方法會一直阻塞在那裏,當有新消息到來時,next 的方法會返回這條消息並將其從單鏈表中移除;

End.

Note by HF.
Learn from 《Android 開發藝術探索》


發佈了104 篇原創文章 · 獲贊 63 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章