在Handler中风喇,我們都會通過發(fā)送Message的方式怪与,在主線程中更新UI。那么系統(tǒng)是如何構(gòu)建Message的隆箩,Message又是如何操作的该贾?
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
在Message的文檔中,建議我們在構(gòu)建Message的時(shí)候通過obtain來構(gòu)建捌臊,通過源碼我們發(fā)現(xiàn)了一個關(guān)鍵詞sPool
杨蛋。而通過字面意思可以理解為Message的消息對象池,但是sPool并不是Map這樣的集合理澎,那么這個對象池到底是什么呢逞力?
// sometimes we store linked lists of these things
/*package*/ Message next;
通過注釋不難發(fā)現(xiàn),Message的消息池并不是一個類似Map的容器糠爬,而是使用的鏈表寇荧。通過next
指定下一個Message。大概意思如下:
next next next
Message -> Message -> Message -> null
這樣所有的Message都通過next串聯(lián)在一起执隧。
通過obtain來獲取Message揩抡,就是通過next來獲取的,并且會將sPoolSize的長度減一镀琉。
但是obtain并沒有添加對象到對象池中峦嗤,那么sPool是如何添加Message的呢?
which will pull them from a pool of recycled objects.
通過注釋發(fā)現(xiàn)創(chuàng)建的時(shí)候并沒有把Message放到對象池中屋摔,而是在回收Message的時(shí)候該對象才會被放到鏈表中烁设。
public void recycle() {
if (isInUse()) {
if (gCheckRecycle) {
throw new IllegalStateException("This message cannot be recycled because it "
+ "is still in use.");
}
return;
}
recycleUnchecked();
}
void recycleUnchecked() {
// Mark the message as in use while it remains in the recycled object pool.
// Clear out all other details.
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) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}
在回收的時(shí)候:
- 首先判斷該消息是否還在使用,如果還在使用則拋出異常
- 清空該消息的各種字段
- 判斷是否要將消息放到對象池中钓试,當(dāng)池的size小于50的時(shí)候装黑,將自己添加到鏈表的表頭副瀑。