publicstaticvoidprepareMainLooper(){ prepare(false); // 创建Looper synchronized (Looper.class) { if (sMainLooper != null) { thrownew IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper();// 将当前的looper对象记录为主线程的Looper } }
privatestaticvoidprepare(boolean quitAllowed){ if (sThreadLocal.get() != null) { thrownew RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); // 将新创建Looper设置到ThreadLocal中 }
publicfinalbooleansendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }
publicbooleansendMessageAtTime(Message msg, long uptimeMillis){ MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); returnfalse; } return enqueueMessage(queue, msg, uptimeMillis); }
booleanenqueueMessage(Message msg, long when){ synchronized (this) { // ...
msg.markInUse(); msg.when = when; Message p = mMessages;// 头指针 boolean needWake; if (p == null || when == 0 || when < p.when) { // 如果头指针为空,或第一个消息的执行时间都晚于新消息,则新消息成为头指针 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; // 加入到列表中 prev.next = msg; // 如果之前没有任务处理,进入了无限阻塞状态,则压入消息后需要唤醒线程 if (needWake) { nativeWake(mPtr); } }
publicstaticvoidloop(){ final Looper me = myLooper(); if (me == null) { // 检测线程中是否存在Looper对象 thrownew RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); }
final MessageQueue queue = me.mQueue;
for (;;) { // 进入死循环 Message msg = queue.next(); // might block,当存在消息后会唤醒线程,推出Message if (msg == null) { // No message indicates that the message queue is quitting. return; }
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. finallong ptr = mPtr; if (ptr == 0) { returnnull; }
int pendingIdleHandlerCount = -1; // -1 only during first iteration int nextPollTimeoutMillis = 0; for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } // 线程休眠nextPollTimeoutMillis时间 nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) { // Try to retrieve the next message. Return if found. finallong now = SystemClock.uptimeMillis(); Message prevMsg = null; Message msg = mMessages; // 如果是msg.target==null则说明遇到了一个同步屏障,会优先取出异步消息 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) { // 当下一个消息的处理时间还没到达,则计算时间差值,当下次运行至nativePollOnce,阻塞相应的时间。 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; msg.markInUse(); return msg; } } else { // No more messages. nextPollTimeoutMillis = -1;// 无消息,则会一直堵塞,等待调用nativeWake唤醒 }
// If first time idle, then get the number of idlers to run. // Idle handles only run if the queue is empty or if the first message // in the queue (possibly a barrier) is due to be handled in the future. if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } if (pendingIdleHandlerCount <= 0) { // 如果当前没有了IdleHandler,更改阻塞标志位,在下一次循环后正式进入阻塞状态 // No idle handlers to run. Loop and wait some more. mBlocked = true; continue; }
if (mPendingIdleHandlers == null) { mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; } mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
} // Run the idle handlers. // We only ever reach this code block during the first iteration. for (int i = 0; i < pendingIdleHandlerCount; i++) { final IdleHandler idler = mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; // release the reference to the handler
// Reset the idle handler count to 0 so we do not run them again. pendingIdleHandlerCount = 0;
// 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; } }
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) { finalint token = mNextBarrierToken++; final Message msg = Message.obtain(); // 获取一个Message对象 msg.markInUse(); msg.when = when; msg.arg1 = token;