/** * Use the {@link Looper} for the current thread with the specified callback interface * and set whether the handler should be asynchronous. * * Handlers are synchronous by default unless this constructor is used to make * one that is strictly asynchronous. * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages. Asynchronous messages are not subject to * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. * * @param callback The callback interface in which to handle messages, or null. * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. * * @hide */ publicHandler(@Nullable Callback callback, boolean async){ if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } }
mLooper = Looper.myLooper(); if (mLooper == null) { thrownew RuntimeException( "Can't create handler inside thread " + Thread.currentThread() + " that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
privateintpostSyncBarrier(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) { // mNextBarrierToken 从 0 开始 finalint token = mNextBarrierToken++; // 障栅消息 final Message msg = Message.obtain(); msg.markInUse(); msg.when = when; msg.arg1 = token;
// 中间变量,用于记录比障栅消息早的最后一个消息(障栅消息的前一个) Message prev = null; // 当前第一条消息 Message p = mMessages; if (when != 0) { // 如果当前消息比障栅消息更早,则不阻塞 while (p != null && p.when <= when) { // 用 prev 记录当前消息 p prev = p; // p 指向下一条消息 p = p.next; } // 循环完成后,会找出所有 when 比障栅消息更小的 Message // 且按照原顺序连接在单链表中,这些消息不会阻塞。 // 此时 LAST 即是 prev,而 p 则指向了 ONEMORE。 } if (prev != null) { // invariant: p == prev.next // 说明循环进到了内部,也即障栅消息将位于 LAST 和 ONEMORE 的中间 // 则障栅消息的下一条为 ONEMORE,即 p msg.next = p; // LAST 的下一条为障栅消息 prev.next = msg; } else { // 说明循环没有进入,也即障栅消息将位于消息队列的首位 // 则障栅消息的下一条为原先消息队列的第一条消息 msg.next = p; // 消息队列的第一条消息变为障栅消息 mMessages = msg; } return token; } }
/** * Removes a synchronization barrier. * * @param token The synchronization barrier token that was returned by * {@link #postSyncBarrier}. * * @throws IllegalStateException if the barrier was not found. * * @hide */ publicvoidremoveSyncBarrier(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; //遍历消息队列的所有元素 // 只有 p.targe == null 且 p.arg1 == token 的才是对应的障栅消息 while (p != null && (p.target != null || p.arg1 != token)) { prev = p; p = p.next; } if (p == null) { thrownew IllegalStateException("The specified message queue synchronization " + " barrier token has not been posted or has already been removed."); } // 是否需要唤醒 finalboolean needWake; if (prev != null) { // 说明目标障栅消息不是第一个消息 // 则将障栅消息的前一条消息的 next 指向障栅消息的下一条 prev.next = p.next; // 因为障栅消息之前有消息,还没有阻塞,所以不需要唤醒 needWake = false; } else { // 如果障栅消息是第一条消息 // 则消息队列的第一条消息直接设置为障栅消息的下一条 mMessages = p.next; // 如果当前消息(原先障栅消息的下一条)为 null,说明消息队列中没有消息 // 如果当前消息的 target != null,说明 needWake = mMessages == null || mMessages.target != null; } p.recycleUnchecked();
// If the loop is quitting then it is already awake. // We can assume mPtr != 0 when mQuitting is false. if (needWake && !mQuitting) { nativeWake(mPtr); } } }