Android消息處理機(jī)制系列文章整體內(nèi)容如下
Android消息處理機(jī)制1——Handler
Android消息處理機(jī)制2——Message
Android消息處理機(jī)制3——MessageQueue
Android消息處理機(jī)制4——Looper
定義
Defines a message containing a description and arbitrary data object that can be sent to a Handler.
這是Android文檔給的定義,翻譯成中文就是:
一個消息對象而叼,這個對象里面主要包含兩部分:Handler的描述和任意的數(shù)據(jù)對象耕突。
Message比較重要的概念的是消息池裙盾。
構(gòu)造器
Message只有一個默認(rèn)構(gòu)造器,不過為了更好的性能夺脾,應(yīng)該避免直接new 一個Message妄壶,而是使用obtain方法從消息池里面獲取一個Message對象。
消息池
Message會維護(hù)一個全局的消息池昧旨,消息池的數(shù)據(jù)類型是一個先進(jìn)后出的鏈?zhǔn)綏!南⒊厝∠⑼ㄟ^obtain()祥得,往消息池添加消息通recycleUnchecked()。
public static Message obtain(Message orig)
public static Message obtain(Handler h)
public static Message obtain(Handler h, Runnable callback)
public static Message obtain(Handler h, int what)
public static Message obtain(Handler h, int what, Object obj)
public static Message obtain(Handler h, int what, int arg1, int arg2)
public static Message obtain(Handler h, int what, int arg1, int arg2, Object obj)
上面的七個方法都會先調(diào)用obatin()方法從消息池里面獲取一個message蒋得,然后再根據(jù)傳入的參數(shù)對message進(jìn)行組裝级及。
取消息
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool; //將當(dāng)前的message對象的引用傳給m
sPool = m.next; //將第二個message(可能為null)的引用傳給sPool
m.next = null; //斷開第一個message和第二個message的聯(lián)系
m.flags = 0; // 清空 in-use標(biāo)志
sPoolSize--; // 將消息池內(nèi)的消息數(shù)量減一
return m;
}
}
return new Message();
}
取 obtain方法里面用的是synchronized,為了防止多個線程同時修改sPool時導(dǎo)致一些奇奇怪怪的事情發(fā)生额衙。
情形一:sPool為null饮焦,則會直接創(chuàng)建一個Message對象怕吴,這個新建的對象會在recycleUnchecked()里面回收,將它放到消息池县踢。最多存放50個message對象转绷。
情形二: sPool中有message對象,則會取出頭部的message硼啤,并且把消息池里的消息數(shù)量減一议经。
插入消息
void recycleUnchecked() {
// 將message標(biāo)記為FLAG_IN_USE
// 清空其他的屬性
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; //讓回收的message的next屬性持有sPool的引用,這樣子谴返,就把這個message放到了鏈?zhǔn)綏5念^部了
sPool = this; //sPool持有當(dāng)前message的引用
sPoolSize++; //消息池內(nèi)的消息數(shù)量加一
}
}
}
當(dāng)消息池里的message數(shù)量小于消息池的最大數(shù)量限制的時候煞肾,將message的屬性清空,并且標(biāo)記為FLAG_IN_USE嗓袱,然后放到消息池這個鏈?zhǔn)綏5念^部
(完)