这是Handler源码学习第二篇,后续还有
handler源码学习(1) — Handler
handler源码学习(2) — Message
handler源码学习(3) — Looper
handler源码学习(4) — MessageQueue
message相对来说比较简单,大部门代码都是对一些属性值的赋值和获取以及Parcelable的实现。这里我们主要看一下几个方法
public Message() {
}
/ 1
public static Message obtain() {
//sPoolSync 锁,因为可能多个线程同时obtain(),所以加锁
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;//将mPool赋值给m
sPool = m.next;//sPool等于链表的m.next。也就是原来的sPool的下一个
m.next = null;//将m.next置为null。至此spoll和m没有链表关系
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
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) {···}
重点看下注释1,其他都是很常规的一些方法。
说白了就是同步取sPool(注意是静态的)的第一个,并且返回。不过这里有个点需要关注,就是什么时候对sPool赋值,什么时候添加next。我们找一下sPool的赋值,很容易找到
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 = UID_NONE;
workSourceUid = UID_NONE;
when = 0;
target = null;
callback = null;
data = null;
//1
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}
其实就是将当前的message的所有变量置为初始状态,同时(注释1)将其添加到sPool(是静态的)的链表头。注释1举个例子:
val 当前msg = this;
spool = 1msg
当前msg.next = 1msg
spool =当前msg(当前msg.next = 1msg)
所以此时的spool就是 当前msg,1msg
所以到这里我们基本上就明白了obtain和直接new Message()的区别。
总结
message就如它的翻译消息。他就是一个标准的消息,里面包含了我们跨线程要传递的东西。
本篇我们解决了问题:
- obtain和直接new Message()的区别
- 消息recycle()后,会被缓存到静态变量sPool中。spool是一个单链表。使用obtainxxx()会直接从sPool中取第一个message来复用。避免了重复创建过多消息对象。
留下疑问:
无