7.3.2 Message的创建和初始化
Message定义于frameworks/base/core/java/android/os/Message.java中,其代码如下:
public final class Message implements Parcelable{
public int what;//消息码,消息接收端以此区分消息类型
……
/package/long when;//指定消息执行的时间
……
/package/Message next;//内部存储下一条消息的引用
private static final Object sPoolSync=new Object();//消息池的锁
private static Message sPool;//消息池
private static int sPoolSize=0;//消息池当前大小
private static final int MAX_POOL_SIZE=50;//消息池最大值
public static Message obtain(){//获取消息的通用方法
synchronized(sPoolSync){
if(sPool!=null){
Message m=sPool;//指向消息池头部
sPool=m.next;//消息池头部指向下一条消息
m.next=null;//当前要处理的消息池
sPoolSize—;//消息池大小减1
return m;//返回从消息池中取到的消息
}
}
return new Message();//消息池为空时创建一个消息
}
public Message(){//构造函数是public的,但仍然推荐使用obtain获取消息
}
//实现Parcelable接口的方法,可以将写入Parcel的对象还原为Message
public static final Parcelable.Creator<Message>CREATOR
=new Parcelable.Creator<Message>(){
public Message createFromParcel(Parcel source){
Message msg=Message.obtain();
msg.readFromParcel(source);
return msg;
}
……
};
……
Message实现了Parcelable接口,因此Message对象可以写入Parcel中,也可以从Parcel中还原已写入的对象,这相当于Java的序列化和反序列化机制。可序列化保证Message对象可以通过Intent或者Binder远程传递。
what成员变量表示消息的消息码,用于唯一标志一条消息。
when成员变量表示消息将在什么时间执行,取值为0表示立即执行。
next成员变量用于表示下一条消息,因此Message本身实现了一个单向链表结构。
sPool成员变量用于表示消息池,每次调用obtain方法相当于取出消息池头部的消息。这里还有一个问题,消息池是如何初始化的?下面分析这部分内容。
消息池的初始化由recycle方法完成,其代码如下:
public void recycle(){
clearForRecycle();//清空消息记录
//将废弃消息投入消息池中重新利用,这样可避免重新创建对象的开销
synchronized(sPoolSync){
if(sPoolSize<MAX_POOL_SIZE){
next=sPool;
sPool=this;//将当前消息加入消息池头部
sPoolSize++;//消息池当前消息数加1
}
}
}
/package/void clearForRecycle(){//清空已使用消息的数据记录
flags=0;
what=0;
arg1=0;
arg2=0;
obj=null;
replyTo=null;
when=0;
target=null;
callback=null;
data=null;
}
使用消息的一方,只需要调用recycle方法便可以把废弃消息放入消息池中以便重新利用。放入消息池的消息已经被清空所有数据,因此不能被立刻使用。如果要使用消息池中存储的消息,就需要调用obtain方法返回消息对象后重新初始化。