Android線程間通信的Message機制
1.1 Message
代碼在frameworks/base/core/java/android/os/Message.java中
Message.obtain函數: 有多個obtain函數, 主要功能一樣,只是參數不一樣。作用是從Message Pool中取出一個Message,如果Message Pool中沒有Message可取,則新建一個Message 返回,同時用對應的參數給得到的Message對象賦值。
Message Pool: 大小爲10個; 通過Message.mPool->(Message並且Message.next)-> (Message並且Message.next)-> (Message並且Message.next)….構造一個Message Pool. Message Pool的第一個元素直接new出來,然後把Message.mPool(static類的static變量)指向它。其他的元素都是使用完的Message通過Message的recycle函數清理後放到Message Pool(通過Message Pool最後一個Message的next指向需要回收的Message的方式實現). 下圖爲Message Pool的結構:
1.2 MessageQueue
MessageQueue裏面有一個收到的Message的隊列.
MessageQueue.mMessage(static變量)->(Message並且Message.next)->(Message並且Message.next)->…..
上層代碼代碼通過 Handler的sendMessage等函數放入一個Message到MessageQueue裏面時最終會調用MessageQueue的enqueeueMessage函數. enqueeueMessage根據上面的接受的Message的隊列的構造把接收到的Message放入隊列中。
MessageQueue中removeMessages函數根據上面的接收的Message的隊列的構造把接收到的Message從隊列中刪除,並且調用對應Message對象的recycle函數把不用的Message放入Message Pool中。
1.3 Looper
Looper對象的創建是通過Prepare函數, 而且每一個Looper對象會和一個線程關聯
Looper對象創建時會創建一個MessageQueue, 主線程默認會創建一個Looper. 從而有MessageQueue. 其他線程默認沒有MessageQueued的不能接收Message, 如果需要接收Messsage, 則需要通過Prepare函數創建一個MessageQueue.
prepareMainLooper函數只給主線程調用(系統處理,程序員不用處理), 它會調用prepare建立Looper對象和MessageQueue.
Looper函數從MessageQueue中從前往後取出Message,然後通過Handler的dispatchMessage函數進行消息的處理(可見消息的處理時Handler負責的), 消息處理完了以後通過Message對象的recycle函數放到Message pool 中, 以便下次使用,通過Pool的處理提供了一定的內存管理從而加速消息對象的獲取。至於需要定時處理的消息如何做到定時處理,請見MessageQueue的next函數,它在取Message來進行處理時通過判斷MessageQueue裏面的Message是哦福複合時間要求來決定是否需要把Message取出來做處理,通過這種方式做到消息的定時處理。
1.3 Handler
Handler的構造函數表示Handler會有成員變量指向Looper和MessageQueue,後面我們會看到沒什麼需要這些引用;至於callback接口對象,後面會看到這個對象的作用。
public Handler(Looper looper, Callback callback) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
}
public interface Callback {
public boolean handleMessage(Message msg);
}
獲取消息:直接通過Message的obtain方法獲取一個Message對象.
發送消息:通過MessageQueue的enqueueMessage把 Message對象放到MessageQueue的接收消息隊列中。
線程如何處理MessageQueue中接收的消息;在Looper的loop函數中循環取出MessageQueue的接收消息隊列中的消息,然後調用Handler的dispatchMessage函數對消息進行處理,至於如何處理(相應消息)則由用戶指定(三個方法,優先級從高到低;Message裏面的Callback,一個實現了Runnable接口的對象,其中run函數做處理工作;Handler裏面的mCallbcak指向的一個實現了Callback接口的對象,裏面的handleMessage進行處理;處理消息Handler對象對應的類繼承並實現了其中的handleMessage函數,通過這個實現的handleMessage函數處理消息);
Runnable說明:Runnable只是一個接口,實現了這個接口的類對應的對象也只是一個普通的對象,並不是一個Java中的Thread.Thread類經常使用Runnable。
其中清理Message是Looper裏面的loop函數指把處理過的Message放到Message的Pool裏面去,如果裏面已經超過最大值10個,則丟棄這個Message對象。
調用Handler是指Looper裏面的loop函數從MessageQueue的接收消息隊列裏面取出消息,然後根據消息指向的Handler對象調用對應的處理方法。