一、Handler的通信機制的背后的原理
Handler的通信機制的背后的原理是,一個線程中可以定義多個 Handler 實例,但是每個 Handler 實際上引用的是同一個 Looper。當然,我們要在創建 Handler 之前先創建 Looper。而每個 Looper 又只對應一個 MessageQueue。該 MessageQueue 會在創建 Looper 的時候被創建。在 MessageQueue 中使用 Message 對象來拼接一個單向的鏈表結構,依次來構成一個消息隊列。每個 Message 是鏈表的一個結點,封裝了我們發送的信息。
Handler 發送消息的方法分成 post 和 send 兩種類型。post 的用來發送 Runnable 類型的數據,send 類型的用來發送 Message 類型的數據。但不論哪種類型最終都會調用 Handler 的 sendMessageAtTime() 方法來加入到 MessageQueue 的隊列中。區別在于,post 類型的方法需要經過 Handler 的 getPostMessage() 包裝成 Message 之后再發送。
當消息被添加到隊列之后需要執行消息,這部分內容在 Looper 的?loop()?方法中。當我們調用 Looper 的 loop() 方法之后整個 Looper 循環就開始不斷地處理消息了。當我們在循環中調用 MessageQueue 的 next() 方法來獲取下一個消息的時候,會調用 nativePollOnce() 方法,該方法可能會造成線程阻塞和非阻塞,當線程為非阻塞的時候就會從 Native 層回到 Java 層,從 MessageQueuue 中取得一個消息之后給 Looper 進行處理。如果獲取的時候造成線程阻塞,那么有兩種情況會喚醒阻塞的線程,一個是當一個新的消息被加入到隊列中,并且將會早于之前隊列的所有消息被觸發,那么此時將會重新設置超時時間。如果達到了超時時間同樣可以從睡眠狀態中返回,也就回到了 Java 層繼續處理。所以,Native 層的 Looper 的作用就是通過阻塞消息隊列獲取消息的過程阻塞 Looper。
延伸閱讀:
二、消息機制的模型有什么
Message:需要傳遞的消息,可以傳遞數據;
MessageQueue:消息隊列,但是它的內部實現并不是用的隊列,實際上是通過一個單鏈表的數據結構來維護消息列表,因為單鏈表在插入和刪除上比較有優勢。主要功能向消息池投遞消息(MessageQueue.enqueueMessage)和取走消息池的消息(MessageQueue.next);
Handler:消息輔助類,主要功能向消息池發送各種消息事件(Handler.sendMessage)和處理相應消息事件(Handler.handleMessage);
Looper:不斷循環執行(Looper.loop),從MessageQueue中讀取消息,按分發機制將消息分發給目標處理者。