Handler訊息機制學習記錄

2020-10-28 16:01:07

示意圖:

類結構示意圖:

時序圖:

從示意圖可以看出來,MessageQueue和子執行緒是一對多的關係,MessageQueue和Looper是 一對一的關係。

那麼如何做到,不同的子執行緒向訊息佇列壓入訊息,拿到的是同一個訊息佇列呢?

      答:把 MessageQueue和Looper繫結好,子執行緒拿到Looper物件,就能拿到MessageQueue對 象。

什麼時候去拿Looper物件?

      答:Looper跟主執行緒是一對一的繫結關係,想要在主執行緒中獲取到Looper物件,那Handler的 範例化就要在主執行緒中進行,所以Looper物件應該在Handler範例化的時候去獲取。

為什麼要在主執行緒更新UI?

      答:系統設計者,為了考慮到使用者體驗,系統效能

子執行緒要更新UI,怎麼辦?

      答:通過訊息機制給主執行緒傳送訊息,讓主執行緒更新UI,這個訊息機制就是Handler

Handler只能用來更新UI嗎?

      答:Handler其實主要用來執行緒通訊 也就是可能會出現子執行緒和子執行緒通訊的情況,那麼輪詢器Looper初始化就有可能出現在 子執行緒中,如何保證Looper物件能夠在子執行緒中被正確獲取,用於loop輪詢呢?答案是 ThreadLocal

ThreadLocal是什麼?

      答:ThreadLocal並不是一個Thread,而是Thread的區域性變數。 ThreadLocal為解決多執行緒的並行問題而生。 它使變數在每個執行緒中都有獨立拷貝,不會出現一個執行緒讀取變數時而被另一個執行緒修改的 現象。

為什麼最終還是要回到handleMessage()這個方法處理次訊息?

      答:因為最終是要回到handleMessage()這個方法,所以先在Message類裡面定義了一個Handler參照target,然後在Handler類的sendMessage方法裡賦值msg.target = this,接著就是在Looper輪詢方法loop裡面取到了Message物件msg,並且直接調(轉發)msg.target.dispatchMessage(msg)方法就可以回到最終是要回到handleMessage()這個方法裡面了。

為什麼要msg.target = this(就是為什麼Message要帶一個target)?

      答:Handler中最少知識原則的應用 Handler既是訊息的傳送者,也是訊息的處理者 只通過一個Handler類就能使用背後極其複雜的訊息機制。

Handler的post()和postDelayed()方法的異同?

  1. 底層都是呼叫的sendMessageDelayed()->sendMessageAtTime()
  2. post()傳入的時間引數為0
  3. postDelayed()傳入的時間引數是需要的時間間隔。