booleanenqueueMessage(Message msg, long when) { // msg的target的Hanlder不允许为空 if (msg.target == null) { thrownewIllegalArgumentException("Message must have a target."); } ... }
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++; // 初始化同步屏障消息。我们可以看到这个消息没有设置target // 这个在Handler里面可是不被允许的!!!! finalMessagemsg= Message.obtain(); msg.markInUse(); msg.when = when; msg.arg1 = token;
/** * * 这个方法主要是进行当前线程里面的message queue队列来遍历消息,进行消息的分发 * 这个我们自己在线程创建的时候自己类执行以下loop()方法 */ publicstaticvoidloop() { // 这个方法就是从TreadLocal里面取得当前的Looper对象。 // 也就是我们每个线程实例化的ThreadLocal对象里面取得保存的Looper对象 finalLooperme= myLooper(); // 毫无疑问,me为null 表示这个线程里面没有进行Looper对象的Looper.prepare()初始化。 if (me == null) { thrownewRuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } // 这个queue就是Looper的构造函数中实例化的mQueue finalMessageQueuequeue= me.mQueue;
// Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); finallongident= Binder.clearCallingIdentity();
// Allow overriding a threshold with a system prop. e.g. // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start' finalintthresholdOverride= SystemProperties.getInt("log.looper." + Process.myUid() + "." + Thread.currentThread().getName() + ".slow", 0);
// 如果为null,表明这个额消息队列正在停止,这个时候就跳出循环。 if (msg == null) { // No message indicates that the message queue is quitting. return; } // Looper里面的由一个logging对象,在消息开始处理的时候,会打印一个Dispatching to // This must be in a local variable, in case a UI event sets the logger finalPrinterlogging= me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } // Make sure the observer won't change while processing a transaction. finalObserverobserver= sObserver;
if (traceTag != 0 && Trace.isTagEnabled(traceTag)) { Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); }
finallongdispatchStart= needStartTime ? SystemClock.uptimeMillis() : 0; finallong dispatchEnd; Objecttoken=null; if (observer != null) { token = observer.messageDispatchStarting(); } longorigWorkSource= ThreadLocalWorkSource.setUid(msg.workSourceUid); // 我们从这个地方调用 msg.target的dispatchMessage()方法 // 那么 msg.target对象是什么? // 其实就是Handler对象 try { msg.target.dispatchMessage(msg); if (observer != null) { observer.messageDispatched(token, msg); } dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0; } catch (Exception exception) { if (observer != null) { observer.dispatchingThrewException(token, msg, exception); } throw exception; } finally { ThreadLocalWorkSource.restore(origWorkSource); if (traceTag != 0) { Trace.traceEnd(traceTag); } } if (logSlowDelivery) { if (slowDeliveryDetected) { if ((dispatchStart - msg.when) <= 10) { Slog.w(TAG, "Drained"); slowDeliveryDetected = false; } } else { if (showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart, "delivery", msg)) { // Once we write a slow delivery log, suppress until the queue drains. slowDeliveryDetected = true; } } } if (logSlowDispatch) { showSlowLog(slowDispatchThresholdMs, dispatchStart, dispatchEnd, "dispatch", msg); } // 消息处理完成完成之后,会打印这个Finished to的日志 if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); }
// Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. finallongnewIdent= Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); }
@UnsupportedAppUsage Message next() { // 如果消息循环已经退出了。则直接在这里return。因为调用disposed()方法后mPtr=0 finallongptr= mPtr; if (ptr == 0) { returnnull; } // 记录空闲时处理的IdlerHandler的数量 intpendingIdleHandlerCount= -1; // -1 only during first iteration // native层用到的变量 ,如果消息尚未到达处理时间,则表示为距离该消息处理事件的总时长, // 表明Native Looper只需要block到消息需要处理的时间就行了。 所以nextPollTimeoutMillis>0表示还有消息待处理 intnextPollTimeoutMillis=0; for (; ; ) { if (nextPollTimeoutMillis != 0) { // 刷新下Binder命令,一般在阻塞前调用 Binder.flushPendingCommands(); } // 调用native层进行消息标示,nextPollTimeoutMillis 为0立即返回,为-1则阻塞等待。 // 就是这行代码进行消息阻塞的。这当代码会调用Native层的Looper的方法 nativePollOnce(ptr, nextPollTimeoutMillis); // 加上同步锁 synchronized (this) { // 获取开机到现在的时间 finallongnow= SystemClock.uptimeMillis(); MessageprevMsg=null; // 获取MessageQueue的链表表头的第一个元素 Messagemsg= mMessages; // 如果msg不为空并且target为空,说明是一个同步屏障消息 // 关于同步屏障的问题,我们可以参考#ViewRootImpl#scheduleTraversals的方法 // 如果是则执行循环,拦截所有同步消息,直到取到第一个异步消息为止 // 进入do while循环,遍历链表,直到找到异步消息msg.isAsynchronous()才跳出循环交给Handler去处理这个异步消息。 if (msg != null && msg.target == null) { // Stalled by a barrier. Find the next asynchronous message in the queue. // 如果能进入这个if,则表面MessageQueue的第一个元素就是障栅(barrier) do { prevMsg = msg; msg = msg.next; //如果msg==null或者msg是异步消息则退出循环,msg==null则意味着已经循环结束 } while (msg != null && !msg.isAsynchronous()); }
// 判断是否有可执行的Message if (msg != null) { // 判断该Mesage是否到了被执行的时间。 if (now < msg.when) { // Next message is not ready. Set a timeout to wake up when it is ready. // 当Message还没有到被执行时间的时候,记录下一次要执行的Message的时间点 nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else { // Got a message. // Message的被执行时间已到 // 从队列中取出该Message,并重新构建原来队列的链接 // 刺客说明说有消息,所以不能阻塞 mBlocked = false; // 如果还有上一个元素 if (prevMsg != null) { //上一个元素的next(越过自己)直接指向下一个元素 prevMsg.next = msg.next; } else { //如果没有上一个元素,则说明是消息队列中的头元素,直接让第二个元素变成头元素 mMessages = msg.next; } // 因为要取出msg,所以msg的next不能指向链表的任何元素,所以next要置为null msg.next = null; if (DEBUG) Log.v(TAG, "Returning message: " + msg); // 标记该Message为正处于使用状态,然后返回Message msg.markInUse(); return msg; } } else { // No more messages. // 没有任何可执行的Message,重置时间 nextPollTimeoutMillis = -1; }
// Process the quit message now that all pending messages have been handled. // 关闭消息队列,返回null,通知Looper停止循环 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)) { pendingIdleHandlerCount = mIdleHandlers.size(); } if (pendingIdleHandlerCount <= 0) { // No idle handlers to run. Loop and wait some more. mBlocked = true; continue; }
// 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; } }
// If the loop is quitting then it is already awake. // We can assume mPtr != 0 when mQuitting is false. if (needWake && !mQuitting) { nativeWake(mPtr); } } }