示意圖:
類結構示意圖:
時序圖:
從示意圖可以看出來,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()方法的異同?