1.调用postSyncBarrier插入target为null的Message
这种消息为屏障消息,返回token,通过token可以移除这个屏障消息
public final class MessageQueue {public int postSyncBarrier() {return postSyncBarrier(SystemClock.uptimeMillis());}private int postSyncBarrier(long when) {// Enqueue a new sync barrier token.// We don't need to wake the queue because the purpose of a barrier is to stall it.synchronized (this) {final int token = mNextBarrierToken++;//创建的Message target为nullfinal Message msg = Message.obtain();msg.markInUse(); //放入链表之前msg.when = when;msg.arg1 = token;Message prev = null;Message p = mMessages;//在链表里,替when找到合适的位置if (when != 0) {while (p != null && p.when <= when) {prev = p;p = p.next;}}//prev p(p要不然为null,要不然p的when大于when)if (prev != null) { // invariant: p == prev.next//prev msg p:msg放在prev和p之间msg.next = p;prev.next = msg;} else {//msg放到表头msg.next = p;mMessages = msg;}return token;}}
}
2.通过Message.next取出异步消息(isAsynchronous()为true)
在获得下一个要处理的Message的时候,如果MessageQueue有屏障消息,那就会pass掉!isAsynchronous()的消息,获得异步消息,对异步消息进行处理。
public final class MessageQueue {Message next() {for (;;) {synchronized (this) {// Try to retrieve the next message. Return if found.final long now = SystemClock.uptimeMillis();Message prevMsg = null;Message msg = mMessages;//如果表头的target为null(屏障消息)if (msg != null && msg.target == null) {//如果表头消息的target为null// Stalled by a barrier. Find the //next asynchronous message in the queue.//遍历,跳过!isAsynchronous()的消息do {prevMsg = msg;msg = msg.next;} while (msg != null && !msg.isAsynchronous());}//msg 为null或者msg的isAsynchronous为true时跳出循环//也就是说如果有屏障消息,那这里的msg要么为null,要么是异步消息//如果没有屏障消息,那这里的msg就是表头if (msg != null) {if (now < msg.when) {//当前时间小于msg的when// Next message is not ready. Set a timeout //to wake up when it is ready.nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);} else {// Got a message.mBlocked = false;//prevMsg msg msg.nextif (prevMsg != null) {prevMsg.next = msg.next;} else {mMessages = msg.next; //更新表头}msg.next = null;msg.markInUse(); //next()返回消息之前调用markInUsereturn msg;}} else {//没有消息// No more messages.nextPollTimeoutMillis = -1;}}}}
}
3.removeSyncBarrier移除屏障消息
根据token找到对应的屏障消息,从链表移除,对这个Message进行回收
public final class MessageQueue {public void removeSyncBarrier(int token) {// Remove a sync barrier token from the queue.// If the queue is no longer stalled by a barrier then wake it.synchronized (this) {Message prev = null;Message p = mMessages;//找target为null且arg1为tokenwhile (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有值prev.next = p.next;needWake = false;} else {mMessages = p.next;//没有消息或者链表头的target不为nullneedWake = mMessages == null || mMessages.target != null; }p.recycleUnchecked(); //回收p// If the loop is quitting then it is already awake.// We can assume mPtr != 0 when mQuitting is false.if (needWake && !mQuitting) {nativeWake(mPtr);}}}
}