privatestaticvoidprepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { thrownewRuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(newLooper(quitAllowed)); }
// MessageQueue.java booleanenqueueMessage(Message msg, long when) { // message 必须指定 Handler if (msg.target == null) { thrownewIllegalArgumentException("Message must have a target."); }
synchronized (this) { if (msg.isInUse()) { thrownewIllegalStateException(msg + " This message is already in use."); }
// 队列退出,不能添加消息 if (mQuitting) { IllegalStateExceptione=newIllegalStateException( msg.target + " sending message to a Handler on a dead thread"); Log.w(TAG, e.getMessage(), e); msg.recycle(); returnfalse; }
msg.markInUse(); msg.when = when; Messagep= mMessages; boolean needWake; // 1. 首次添加消息; 2. 即时消息; 3. 延迟事件小于头节点的时间 // 这三种情况才更新头节点 if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else {// 将消息插入到链表的非首部位置 // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; for (;;) { prev = p; p = p.next; // 根据时间从小到大插入到链表中 if (p == null || when < p.when) { break; } if (needWake && p.isAsynchronous()) { needWake = false; } } // 更新链表,插入消息 msg.next = p; // invariant: p == prev.next prev.next = msg; }
// We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } returntrue; }
// MessageQueue.java Message next() { // Return here if the message loop has already quit and been disposed. // This can happen if the application tries to restart a looper after quit // which is not supported. finallongptr= mPtr; if (ptr == 0) { returnnull; }
intpendingIdleHandlerCount= -1; // -1 only during first iteration intnextPollTimeoutMillis=0; for (;;) { // 非首次调用 if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } // 调用 native 方法阻塞 nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) { // Try to retrieve the next message. Return if found. finallongnow= SystemClock.uptimeMillis(); MessageprevMsg=null; Messagemsg= mMessages; // 如果遇到同步屏障,遍历查找之后的异步消息 if (msg != null && msg.target == null) { // Stalled by a barrier. Find the next asynchronous message in the queue. do { prevMsg = msg; msg = msg.next; } while (msg != null && !msg.isAsynchronous()); } // 链表首部消息或异步消息 if (msg != null) { // 消息时间大于当前时间,计算阻塞时间 if (now < 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; if (prevMsg != null) {// 异步消息 prevMsg.next = msg.next; } else {// 同步消息 mMessages = msg.next; } msg.next = null; if (DEBUG) Log.v(TAG, "Returning message: " + msg); msg.markInUse(); return msg; } } else { // No more messages. nextPollTimeoutMillis = -1; }
// Process the quit message now that all pending messages have been handled. if (mQuitting) { dispose(); returnnull; }
// 初始化 IdleHandler }
// 执行 IdleHandler。1. 消息队列空;2.首部消息不到执行时间
// While calling an idle handler, a new message could have been delivered // so go back and look again for a pending message without waiting. nextPollTimeoutMillis = 0; } }
privatestaticvoidprepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { thrownewRuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(newLooper(quitAllowed)); }
@Deprecated publicstaticvoidprepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { thrownewIllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } }
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) { finalinttoken= mNextBarrierToken++; finalMessagemsg= Message.obtain(); msg.markInUse(); msg.when = when; msg.arg1 = token; // 没有设置 target
@UnsupportedAppUsage @TestApi 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) { Messageprev=null; Messagep= mMessages; while (p != null && (p.target != null || p.arg1 != token)) { prev = p; p = p.next; } if (p == null) { thrownewIllegalStateException("The specified message queue synchronization " + " barrier token has not been posted or has already been removed."); } finalboolean needWake; if (prev != null) { prev.next = p.next; needWake = false; } else { mMessages = p.next; 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); } } }
Message next() { intpendingIdleHandlerCount= -1; // -1 only during first iteration for (;;) { // 从 mMessages 链表中获取 Message
// Process the quit message now that all pending messages have been handled. if (mQuitting) { dispose(); returnnull; }
// 首次执行 IdleHandler if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } if (pendingIdleHandlerCount <= 0) { // No idle handlers to run. Loop and wait some more. mBlocked = true; continue; } if (mPendingIdleHandlers == null) { mPendingIdleHandlers = newIdleHandler[Math.max(pendingIdleHandlerCount, 4)]; } mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); }
// Run the idle handlers. // We only ever reach this code block during the first iteration. for (inti=0; i < pendingIdleHandlerCount; i++) { finalIdleHandleridler= mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; // release the reference to the handler
if (!keep) { synchronized (this) { mIdleHandlers.remove(idler); } } }
// Reset the idle handler count to 0 so we do not run them again. // 所有 IdleHandler 处理完毕,重置为 0,退出 IdleHandler 循环。 // 如果还没有消息可以处理,休眠。 pendingIdleHandlerCount = 0; nextPollTimeoutMillis = 0; }
/** * Callback interface for discovering when a thread is going to block * waiting for more messages. */ publicstaticinterfaceIdleHandler { // 返回 true:保留 IdleHandler,重复使用;false:只使用一次 booleanqueueIdle(); } }