天天看點

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

在研究源碼之前,我們對Handler的了解一般是這樣的概念:

在主線程中,有消息隊列Looper,裡面有很多的消息,還有一個Handler,用來向Looper發送消息,Looper會将消息接收,不停的取出新消息,并把消息配置設定給Handler執行,同時,Handler從回收的消息隊列中(Message.obtain())擷取消息進行複用,再發出新消息,這就構成了Handler的消息機制.

現在,我們就來深入分析一下這裡面的具體實作過程.

一.Handler擷取Message對象及Message的複用

在Handler的源碼中,我們可以發現, Handler.obtainMessage() 方法的傳回值,其實就是Message.obtain(),隻不過每個方法的傳回參數不同.

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用
Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用
Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用
Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用
Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

是以,在複用消息對象的時候,使用Handler.obtainMessage() 方法和Message.obtain()方法其實是相同的.而Message.obtain()的方法,都依賴空參的obtain()方法來生成資料,

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

是以,我們隻需要研究空參的obtain方法即可.

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

通過檢視源碼可知,空參的obtain()涉及靜态變量Message對象 mPool和非靜态的Message 對象next.說明每個消息對象都有next屬性,而mPool是所有子類共用的.

然後,我們再看Message類中的recycle()方法,也就是用來回收的方法:

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

在recycle()方法裡面做了一個判斷,如果mPoolSize<MAX_POOL_SIZE,就調用clearForRecycle()方法,把目前的消息對象的所有參數全部清空,可以說,當消息回收的時候,消息對象就被還原成了剛建立時的狀态.

是以,消息回收時都做了什麼呢?我們畫圖分析一下:

每個msg對象都有一個next屬性,而所有的msg對象共用一個mPool屬性,這個前面我們已經說過.一開始的mPool值為null,recycle方法調用時,讓next=mPool,而mPool=this,把mPool指向了目前的msg對象,

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

這時如果再回收一個msg對象,新的msg對象的next屬性就指向了mPool,也就是上一個msg對象,而mPool指向了目前的msg對象.以此類推,就形成了回收的消息隊列.

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用
Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

接着我們再回到Message的obtain方法:

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

obtain方法判斷mPool是否為空,不為空的情況下,設定一個局部變量m,把m指向mPool也就是最新的對象

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

mPool指向了m的next對象,也就是上一個msg對象:

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

接下來将m.next指派為null,斷開了與後面的msg對象的聯系:

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

然後把m給return回去,于是一條幹淨的msg就被提供給Handler進行複用了.消息隊列變成了:

Android源碼分析----------Handler消息機制(1)Handler擷取Message對象及Message的複用

接下來,再判斷mPool是否為空,仍不為空的話繼續重複上面的操作.直至mPool為空時,建立一條新的消息.

也就是說,Handler在通過Message.obtain()擷取消息時,如果有消息,就複用,沒有的話,就new一條新消息.