本文基于 SDK-33
public Message() {
}
该方法会直接创建一个 Message 对象,但不推荐使用。
该方法会在消息池中返回一个 Message 对象,如果消息池中为空,才会创建新对象
public static Message obtain() {
synchronized (sPoolSync) {//因为可能在不同线程中调用该方法创建 Message 对象,所以需要加锁保证线程安全
if (sPool != null) {//消息池头部不为null,表示消息池不为空
Message m = sPool;//获取池头消息
sPool = m.next;//将第二个消息标记为池头
m.next = null;//将原池头消息中标识的下一个消息清空
m.flags = 0; //将原池头消息的标记清零
sPoolSize--;//池中消息数量 -1
return m;//返回消息
}
}
return new Message();//如果消息池为空,就创建新 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;
m.workSourceUid = orig.workSourceUid;
if (orig.data != null) {
m.data = new Bundle(orig.data);
}
m.target = orig.target;
m.callback = orig.callback;
return m;
}
//指定消息的 target
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
//指定消息的 target 和 callback
public static Message obtain(Handler h, Runnable callback) {
Message m = obtain();
m.target = h;
m.callback = callback;
return m;
}
//指定消息的 target 和 what
public static Message obtain(Handler h, int what) {
Message m = obtain();
m.target = h;
m.what = what;
return m;
}
//指定消息的 target 和 what 和 obj
public static Message obtain(Handler h, int what, Object obj) {
Message m = obtain();
m.target = h;
m.what = what;
m.obj = obj;
return m;
}
//指定消息的 target 和 what 和 arg1 arg2
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;
}
//指定消息的 target 和 what 和 arg1 arg2 和 obj
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;
}
public void recycle() {
if (isInUse()) {//如果消息正在使用中
if (gCheckRecycle) {//如果设置了回收检测,则抛出异常,如果没有设置回收检测,则直接返回,不进行回收
throw new IllegalStateException("This message cannot be recycled because it "
+ "is still in use.");
}
return;
}
recycleUnchecked();//如果没有正在使用,则进行回收
}
/**
* Recycles a Message that may be in-use.
* Used internally by the MessageQueue and Looper when disposing of queued Messages.
*/
@UnsupportedAppUsage
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;//设置消息 flag
what = 0;//清除 Message 的各种属性
arg1 = 0;
arg2 = 0;
obj = null;
replyTo = null;
sendingUid = UID_NONE;
workSourceUid = UID_NONE;
when = 0;
target = null;
callback = null;
data = null;
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {//如果此时消息池内消息数量还没到允许的最大数
next = sPool;//将原池内头部消息的next 指向原消息头
sPool = this;//将回收的消息作为消息头
sPoolSize++;//池内消息数量 +1
}
}
}
static final int FLAG_ASYNCHRONOUS = 1 << 1;
public boolean isAsynchronous() {
return (flags & FLAG_ASYNCHRONOUS) != 0;
}
public void setAsynchronous(boolean async) {
if (async) {
flags |= FLAG_ASYNCHRONOUS;
} else {
flags &= ~FLAG_ASYNCHRONOUS;
}
}
可以通过 setAsynchronous(true)
将消息设置为异步消息。如果消息是异步消息,则 isAsynchronous()
方法会返回 true。
异步消息主要和同步消息屏障配合使用,在 MessageQueue 源码分析中有讲解。