/* * @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(Callback callback, boolean async) { mLooper = Looper.myLooper();// 使用当前线程所在的Looper if (mLooper == null) { thrownewRuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; //标志Message是否为异步Message.setAsynchronous } /* * @hide */ publicHandler(Looper looper, Callback callback, boolean async) { mLooper = looper; // 为handler指定Looper mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }
/** * Recycles a Message that may be in-use. * Used internally by the MessageQueue and Looper when disposing of queued Messages. */ voidrecycleUnchecked() { // Mark the message as in use while it remains in the recycled object pool. // Clear out all other details. flags = FLAG_IN_USE; // 标示为in_use_flag what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; sendingUid = -1; when = 0; target = null; callback = null; data = null; synchronized (sPoolSync) { // 最多可以缓存50个Message if (sPoolSize < MAX_POOL_SIZE**(50)**) { // 将缓存的sPool指向当前msg,next指向原有的sPool next = sPool; sPool = this; sPoolSize++; } } }
privatestaticvoidprepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { thrownew RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
publicstaticvoidloop() { finalLooperme= myLooper(); // 获取当前线程所在 Looper,不能为空 if (me == null) { thrownewRuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } finalMessageQueuequeue= me.mQueue; Binder.clearCallingIdentity(); finallongident= Binder.clearCallingIdentity(); for (;;) { // 循环从MQ中取出消息,没有消息则阻塞 Messagemsg= queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } // 交给相关Handler处理消息 **msg.target.dispatchMessage(msg);** // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. finallongnewIdent= Binder.clearCallingIdentity(); msg.recycleUnchecked(); // 消息回收 } }
// 添加消息到消息队列, 最终的mMessages是按照when的由小到大排列 boolean enqueueMessage(Message msg, long when) { // 检查msg合法性,必须包含handler且非FLAG_IN_USE状态 if (msg.target == null) { thrownew IllegalArgumentException("Message must have a target."); } if (msg.isInUse()) { thrownew IllegalStateException(msg + " This message is already in use."); } synchronized (this) { if (mQuitting) { //如果已经调用MessageQueue.quit, 那么不再接收新的Message msg.recycle(); returnfalse; } msg.markInUse();// msg in_use_flag msg.when = when; Message p = mMessages; boolean needWake; // 队列为空或msg.when == 0或 msg.when < mMessages.when时 // 将msg直接插入到队列头部 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; // 根据when的大小顺序,插入到合适的位置 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); //唤醒nativeMessageQueue } } returntrue; }
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 空闲handler数量 int nextPollTimeoutMillis = 0; // MQ阻塞时间 for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } nativePollOnce(ptr, nextPollTimeoutMillis); //MessageQueue阻塞nextPollTimeoutMillis 指定时间 synchronized (this) { // Try to retrieve the next message. Return if found. finallong now = SystemClock.uptimeMillis(); // 开机相对时间(不包含休眠时间) Message prevMsg = null; Message msg = 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) { // 遇到延迟消息,则阻塞一段时间 nextPollTimeoutMillis // 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. // 得到Message,从MQ里移除此消息 mBlocked = false; if (prevMsg != null) { // prevMsg != null,说明是同步分隔栏消息, prevMsg.next = msg.next; // 保留MQ头部为同步分隔栏消息(为了取出下一个异步消息),替换next消息 } else { mMessages = msg.next; // 不包含同步分隔栏消息,替换当前head为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; } // 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)) { // 线程空闲,计算IdleHandler的数量 pendingIdleHandlerCount = mIdleHandlers.size(); } // 没有IdleHandler 阻塞队列 if (pendingIdleHandlerCount <= 0) { // 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. // 处理IdleHandler部分 for (int i = 0; i < pendingIdleHandlerCount; i++) { final IdleHandler idler = mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; // release the reference to the handler boolean keep = false; try { keep = idler.queueIdle(); } catch (Throwable t) { Log.wtf(TAG, "IdleHandler threw exception", t); } // 是否需要移除IdleHandler if (!keep) { synchronized (this) { mIdleHandlers.remove(idler); } } } // 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; } }