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文檔給的定義,翻譯成中文就是:
一個(gè)消息對(duì)象,這個(gè)對(duì)象里面主要包含兩部分:Handler的描述和任意的數(shù)據(jù)對(duì)象。
Message比較重要的概念的是消息池。
構(gòu)造器
Message只有一個(gè)默認(rèn)構(gòu)造器,不過(guò)為了更好的性能,應(yīng)該避免直接new 一個(gè)Message,而是使用obtain方法從消息池里面獲取一個(gè)Message對(duì)象。
消息池
Message會(huì)維護(hù)一個(gè)全局的消息池,消息池的數(shù)據(jù)類(lèi)型是一個(gè)先進(jìn)后出的鏈?zhǔn)綏!南⒊厝∠⑼ㄟ^(guò)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)
上面的七個(gè)方法都會(huì)先調(diào)用obatin()方法從消息池里面獲取一個(gè)message,然后再根據(jù)傳入的參數(shù)對(duì)message進(jìn)行組裝。
取消息
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool; //將當(dāng)前的message對(duì)象的引用傳給m
sPool = m.next; //將第二個(gè)message(可能為null)的引用傳給sPool
m.next = null; //斷開(kāi)第一個(gè)message和第二個(gè)message的聯(lián)系
m.flags = 0; // 清空 in-use標(biāo)志
sPoolSize--; // 將消息池內(nèi)的消息數(shù)量減一
return m;
}
}
return new Message();
}
取 obtain方法里面用的是synchronized,為了防止多個(gè)線程同時(shí)修改sPool時(shí)導(dǎo)致一些奇奇怪怪的事情發(fā)生。
情形一:sPool為null,則會(huì)直接創(chuàng)建一個(gè)Message對(duì)象,這個(gè)新建的對(duì)象會(huì)在recycleUnchecked()里面回收,將它放到消息池。最多存放50個(gè)message對(duì)象。
情形二: sPool中有message對(duì)象,則會(huì)取出頭部的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的引用,這樣子,就把這個(gè)message放到了鏈?zhǔn)綏5念^部了
sPool = this; //sPool持有當(dāng)前message的引用
sPoolSize++; //消息池內(nèi)的消息數(shù)量加一
}
}
}
當(dāng)消息池里的message數(shù)量小于消息池的最大數(shù)量限制的時(shí)候,將message的屬性清空,并且標(biāo)記為FLAG_IN_USE,然后放到消息池這個(gè)鏈?zhǔn)綏5念^部
(完)