Message是比较没存在感的类,用法比较简单,它是一个final类,也就是说此类无法继承。先从简单的看起。全局变量(public类):
public int what;//消息标示,
public int arg1; //简单int类型数据
public int arg2;//简单int类型数据
public Object obj;//简单Object类型数据
public Messenger replyTo;//跨进程信使
public int sendingUid = -1;//Messenger消息标示
全局变量(package类):
/*package*/ static final int FLAG_IN_USE = 1 << 0;//正在使用中
/*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1;//消息同步标识
/*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE;//
/*package*/ int flags;//消息执行标识
/*package*/ long when;//执行时间
/*package*/ Bundle data;//装载的数据
/*package*/ Handler target;//目标载体
/*package*/ Runnable callback;//任务线程
/*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;//消息池最大消息数常量
private static boolean gCheckRecycle = true;//循环检查
Message的构造方法主要有两类,一类是Google推荐的,另一类是我们普通不推荐的。
推荐构造方法:
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
public static Message obtain(Message orig) {
Message m = obtain();
m.what = orig.what;
m.arg1 = orig.arg1;
m.arg2 = orig.arg2;
m.obj = orig.obj;
m.replyTo = orig.replyTo;
m.sendingUid = orig.sendingUid;
if (orig.data != null) {
m.data = new Bundle(orig.data);
}
m.target = orig.target;
m.callback = orig.callback;
return m;
}
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
public static Message obtain(Handler h, Runnable callback) {
Message m = obtain();
m.target = h;
m.callback = callback;
return m;
}
public static Message obtain(Handler h, int what) {
Message m = obtain();
m.target = h;
m.what = what;
return m;
}
public static Message obtain(Handler h, int what, Object obj) {
Message m = obtain();
m.target = h;
m.what = what;
m.obj = obj;
return m;
}
public static Message obtain(Handler h, int what, int arg1, int arg2) {
Message m = obtain();
m.target = h;
m.what = what;
m.arg1 = arg1;
m.arg2 = arg2;
return m;
}
public static Message obtain(Handler h, int what,int arg1, int arg2, Object obj) {
Message m = obtain();
m.target = h;
m.what = what;
m.arg1 = arg1;
m.arg2 = arg2;
m.obj = obj;
return m;
}
第一个的obtain()方法是默认主要方法,后面都是对应的各种构造方法,而且Handler类里面obtainMessae方法都是直接调用Message对应的构造方法!
来看主要的构造方法obtain(),先直接加锁,然后判断消息池里面的的Message是否为空,不为空的话获取这个消息对象,然后将消息池获取下一个链表消息,并置当前的消息链表,清除使用标识,减少消息池size数量,然后返回消息,也就是Message的复用。如果为空的话,则直接调用第二种方法构造并返回。
public Message() {
}
也就是普通的构造方法。这也是为什么我们常常看见代码里面使用obtain方法获取Message对象实例而不是直接new的原因。
构造方法讲完了基本就是变量赋值,然后添加到消息队列中!其他的方法主要是一些全局变量的赋值或获取方法,没啥可说的。直接来看看消息的回收,也就是消息池的初始化:
void recycleUnchecked() {
// Mark the message as in use while it remains in the recycled object pool.
// Clear out all other details.
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;
sPool = this;
sPoolSize++;
}
}
}
消息池的初始化是检查回收的时候将当前消息对象赋值给消息池的,且赋值前已经清除了所有变量,并初始化了消息并且消息链表的消息指向未赋值前的消息池,形成链表结构!
再来看看调用的方法:
public void recycle() {
if (isInUse()) {
if (gCheckRecycle) {
throw new IllegalStateException("This message cannot be recycled because it "
+ "is still in use.");
}
return;
}
recycleUnchecked();
}
消息的回收,回收前直接做了判断,所以不存在Message没有使用就直接回收的情况。而且这个是public方法,也就是提供给外部调用的,而和Message直接相关的除了Handler也就是MessageQueue了,这里Handler是目标载体,而且回收的时候都释放了,不合理。也就只有MessageQueue了,去MessageQueue查找会发现在enqueueMessage方法中有调用,而且还是限定的私有方法(虽然没写方法修饰符,但MessageQueue也是final类,无法继承)。
Message类基本就是这些吧,也没啥可讲的了,下节我们来深入的了解MessageQueue!