Message的獲取方式除了new Message這種方式,Message類還提供了obtain方法來獲取Message
//Message類中有一個靜態(tài)全局變量來儲存空閑或者回收的Message對象private static Message sPool;public static Message obtain() { synchronized (sPoolSync) { if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null; m.flags = 0; sPoolSize--; return m; } } return new Message(); }這種方式是把靜態(tài)全局變量sPool(這里可以把這個Message看做當前消息池中的第一條消息)標記為未使用然后返回,如果sPool為null才會創(chuàng)建新的Message對象,這樣不會造成資源的浪費,避免創(chuàng)建太多Message對象。關(guān)于為什么sPool會是被回收的Message對象,上源碼:
//此方法為Message的回收方法 public void recycle() { //在回收的方法 recycleUnchecked(); }; void recycleUnchecked() { //這里在做一些重置的工作 flags = FLAG_IN_USE; what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; sendingUid = -1; when = 0; target = null; callback = null; data = null; synchronized (sPoolSync) { //當消息池里消息的數(shù)量小于消息池的最大容量時 if (sPoolSize < MAX_POOL_SIZE) { //重點?。?! /*把當前消息池中第一條消息(也就是sPool)置為當前消息的下一條消息(sPool為 全局靜態(tài)變量,所有Message都共用這一個sPool)*/ next = sPool; /*把當前消息置為消息池中第一條消息(因為上一步驟已經(jīng)把原來消息池中的第一條消息置為 了當前消息的下一條消息,現(xiàn)在把當前消息置為消息池中的第一條消息,所以sPool永遠代表 消息池中的第一條消息)*/ sPool = this; sPoolSize++; } } }可以看出Message在回收過程中,只要消息池的數(shù)量小于消息池的最大容量時,就是把當前Message放入消息池中。
從Message入列方式我們也看出,再有新消息進入隊列時,是先判斷新消息的觸發(fā)時間,找出消息應該插入消息隊列的位置,把這個位置的消息的next置為本條新消息,然后把新消息的next置為這個位置的消息的下一條消息。類似以下結(jié)構(gòu)(如果我理解有錯,歡迎指出)。

系列目錄:
一定搞懂Handler消息處理機制系列之「01.Handler消息發(fā)送」
一定搞懂Handler消息處理機制系列之「02.Message入列」
一定搞懂Handler消息處理機制系列之「03.MessageQueue與Looper的由來」
一定搞懂Handler消息處理機制系列之「04.Message是如何觸發(fā)的」
新聞熱點
疑難解答