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方法返回消息对象后重新初始化。