Android消息处理机制系列文章整体内容如下
Android消息处理机制1——Handler
Android消息处理机制2——Message
Android消息处理机制3——MessageQueue
Android消息处理机制4——Looper
定义
Defines a message containing a description and arbitrary data object that can be sent to a Handler.
这是Android文档给的定义,翻译成中文就是:
一个消息对象,这个对象里面主要包含两部分:Handler的描述和任意的数据对象。
Message比较重要的概念的是消息池。
构造器
Message只有一个默认构造器,不过为了更好的性能,应该避免直接new 一个Message,而是使用obtain方法从消息池里面获取一个Message对象。
消息池
Message会维护一个全局的消息池,消息池的数据类型是一个先进后出的链式栈。从消息池取消息通过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)
上面的七个方法都会先调用obatin()方法从消息池里面获取一个message,然后再根据传入的参数对message进行组装。
取消息
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool; //将当前的message对象的引用传给m
sPool = m.next; //将第二个message(可能为null)的引用传给sPool
m.next = null; //断开第一个message和第二个message的联系
m.flags = 0; // 清空 in-use标志
sPoolSize--; // 将消息池内的消息数量减一
return m;
}
}
return new Message();
}
取 obtain方法里面用的是synchronized,为了防止多个线程同时修改sPool时导致一些奇奇怪怪的事情发生。
情形一:sPool为null,则会直接创建一个Message对象,这个新建的对象会在recycleUnchecked()里面回收,将它放到消息池。最多存放50个message对象。
情形二: sPool中有message对象,则会取出头部的message,并且把消息池里的消息数量减一。
插入消息
void recycleUnchecked() {
// 将message标记为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放到了链式栈的头部了
sPool = this; //sPool持有当前message的引用
sPoolSize++; //消息池内的消息数量加一
}
}
}
当消息池里的message数量小于消息池的最大数量限制的时候,将message的属性清空,并且标记为FLAG_IN_USE,然后放到消息池这个链式栈的头部
(完)