/** * Callback interface you can use when instantiating a Handler to avoid * having to implement your own subclass of Handler. */ publicinterfaceCallback{ /** * @param msg A {@link android.os.Message Message} object * @return True if no further handling is desired */ publicbooleanhandleMessage(Message msg); } /** * Subclasses must implement this to receive messages. */ publicvoidhandleMessage(Message msg) { }
/** * Handle system messages here. */ publicvoiddispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
publicstaticvoidloop() { finalLooperme= myLooper(); if (me == null) { thrownewRuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } finalMessageQueuequeue= me.mQueue;
...
for (;;) { Messagemsg= queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } ... try { msg.target.dispatchMessage(msg); dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0; } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } ...
msg.recycleUnchecked(); } } /** * Return the Looper object associated with the current thread. Returns * null if the calling thread is not associated with a Looper. */ publicstatic@Nullable Looper myLooper() { return sThreadLocal.get(); }
privatestaticvoidprepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { thrownew RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
boolean enqueueMessage(Message msg, long when) { if (msg.target == null) { //不是异步消息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) { // 退出 IllegalStateException e = new IllegalStateException( 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; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { // 如果上一个Message为null,或者 延迟时间为0,或者当前消息的延时小于上一个消息,应该更早的被执行 // New head, wake up the event queue if blocked. msg.next = p; // msg应该被放置到头部,上一个消息在该消息的后面 mMessages = msg; needWake = mBlocked; } else { // 这段逻辑就是找到msg链式结构的合适位置 // 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; }
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; } // 用来保存注册到消息队列中的空闲消息处理器(IdleHandler)的个数,当消息队列 // 没有新消息需要处理时,不是马上进入睡眠等待状态,而是先调用已注册的IdleHandler // 对象的queueIdle(...)函数,以便有机会进行空闲处理。 int pendingIdleHandlerCount = -1; // -1 only during first iteration // 若没有新消息待处理,线程睡眠等待的时间。 // 0表示不要进入睡眠等待状态;-1表示若无新消息,则永久睡眠等待 int nextPollTimeoutMillis = 0; for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); }
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) { // 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 { //当前消息指向下一个队头消息,这个无限的循环就是不停的获取消息,而我们消息在入队的时候已经插入到合适的位置,所以这里只要挨个遍历就好,如果发现当前时间小于消息要被执行的时间就调用nativePollOnce(ptr, nextPollTimeoutMillis)进行阻塞 mMessages = msg.next; } msg.next = null; if (DEBUG) Log.v(TAG, "Returning message: " + msg); msg.markInUse(); return msg; } } else { // No more messages. nextPollTimeoutMillis = -1; }