//循环遍历,将这个同步屏障msg插入到队列
Message prev = null;
Message p = mMessages;
//遍历查找when之前的消息
if (when != 0) {
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
}
//插入到队列
if (prev != null) {
msg.next = p;
prev.next = msg;
} else {
msg.next = p;
mMessages = msg;
}
return token;
}
}
再来看看removeSyncBarrier():
//这个token就是我们上面保存的
public void removeSyncBarrier(int token) {
synchronized (this) {
//遍历删除这个token对应的msg
Message prev = null;
Message p = mMessages;
//只要p.target!=null || p.arg1!=token就一直找,因为上面我们分析了同步屏障的target=null,并且arg1=token
while (p != null && (p.target != null || p.arg1 != token)) {
prev = p;
p = p.next;
}
//检测队列
if (p == null) {
throw new IllegalStateException("The specified message queue synchronization "
- " barrier token has not been posted or has already been removed.");
}
final boolean needWake;
//移除同步屏障消息
if (prev != null) {
prev.next = p.next;
needWake = false;
} else {
mMessages = p.next;
needWake = mMessages == null || mMessages.target != null;
}
//回收
p.recycleUnchecked();
//如果需要唤醒,则唤醒等待
if (needWake && !mQuitting) {
nativeWake(mPtr);
}
}
}
然后看mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);第一个参数是个int,第二个参数mTraversalRunnable是个Runnable,代码如下:
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
void doTraversal() {
if (mTraversalScheduled) { //不在执行中才执行
mTraversalScheduled = false; //更新标记为执行中
//从mHandler的MesssageQueue中移除同步屏障,还记得刚刚添加同步屏障的代码吗
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
//开始遍历布局
performTraversals();
}
}
//这个方法对view进行了测量,布局和绘制,我们后面会细讲
private void performTraversals() {
…
performMeasure();
…
performLayout();
…
performDraw();
…
}<