publicHandler(Callback callback, boolean async){ //检查潜在的泄漏 if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } }
//获取当前线程的Looper mLooper = Looper.myLooper(); //Handler需要Looper,如果为null,抛出异常 if (mLooper == null) { thrownew RuntimeException( "Can't create handler inside thread " + Thread.currentThread() + " that has not called Looper.prepare()"); } //设置当前Handler的MessageQueue 等于Looper的MessageQueue mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
//获取当前线程的map,并返回looper public T get(){ Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } //如果当前线程的map还没有,就在这个方法里面创建 return setInitialValue(); }
再看一下 Looper.prepare(),这里解释了为什么只能调用一次
1 2 3 4 5 6 7 8
privatestaticvoidprepare(boolean quitAllowed){ //如果有了,就抛错,一个线程保证了只能有一个Looper if (sThreadLocal.get() != null) { thrownew RuntimeException("Only one Looper may be created per thread"); } //没有就new一个 set sThreadLocal.set(new Looper(quitAllowed)); }
booleanenqueueMessage(Message msg, long when){ //target 就是发送消息的Hander 如果message的handelr为null,抛错 if (msg.target == null) { thrownew IllegalArgumentException("Message must have a target."); }
//msg是不是正在被使用,比如说这个消息已经入队了。就不能再加入 // 连续sendMessage同一个msg对象就会抛错,当然msg复用obtian和new的时候FLAG_IN_USE会重置 if (msg.isInUse()) { thrownew IllegalStateException(msg + " This message is already in use."); } //保证线程安全 synchronized (this) { //当前队列是不是调用了quit 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; } //标记为Use状态 msg.markInUse(); msg.when = when; //先保留之前的节点,准备插入现在的msg Message p = mMessages; boolean needWake;
//p = null 现在队列是空的 // 为什么 会有 when = 0 ?Handler提供了一个sendMessageAtFrontOfQueue 方法,保证某个消息插到消息头,及时处理 //when < p.when 当前插入的消息 比前一个节点的时间更小,意味着要先执行消息 //其实就是头插入 类似 null<--msg 或者 null<--.<--p<--msg if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; //根据当前的MessageQueue 状态,确定是否要唤醒队列起来处理消息 //为什么要唤醒?因为队列为空了,或者队列里面的消息都是明天才要处理的,那么今晚可以睡觉。但是睡梦中又有新的(bug)消息来了,就是这次要插入的消息,必须起来处理(bug)消息 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. //以上情况不满足,就是要把当前这个消息插入到队列中间去了 // 就按时间when的顺序插入 //当前 消息队列是否阻塞 && 队头的消息target=null && 是否支持异步 //target == null 为什么可以为null?不是不能为null吗?见后面 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. //是否需要唤醒?mPtr used by native code if (needWake) { nativeWake(mPtr); } } returntrue; }
publicstaticvoidloop(){ //获取当前线程的Looper final Looper me = myLooper(); if (me == null) { thrownew RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = 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. //清空远程调用端的uid和pid,用当前本地进程的uid和pid替代; Binder.clearCallingIdentity(); finallong ident = Binder.clearCallingIdentity();
// Allow overriding a threshold with a system prop. e.g. // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start' finalint thresholdOverride = SystemProperties.getInt("log.looper." + Process.myUid() + "." + Thread.currentThread().getName() + ".slow", 0);
boolean slowDeliveryDetected = false; //这里开始处理消息,死循环 for (;;) { //这里可能阻塞,现在没有消息需要处理的消息 Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. //msg = null,消息队列退出了,退出死循环 return; }
// This must be in a local variable, in case a UI event sets the logger //每次更新log,防止被set了最新的了,打印分发log final Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); }
//下面主要是打印log,消息处理可能延时 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); }
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. finallong newIdent = 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); }
/** * 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; what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; sendingUid = -1; when = 0; target = null; callback = null; data = null;
synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { next = sPool; sPool = this; sPoolSize++; } } }
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; //mPtr 退出了, return null,前面的 Looper.loop 收到null消息就退出死循环了 if (ptr == 0) { returnnull; }
//什么是 IdleHandler ?见后面 //这个现在主要做标记 int pendingIdleHandlerCount = -1; // -1 only during first iteration // 休息时间 int nextPollTimeoutMillis = 0; for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } //本地方法 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 != null,但是target = null,前面说了这个是barrier消息 if (msg != null && msg.target == null) { // Stalled by a barrier. Find the next asynchronous message in the queue. //继续寻找下一个barrier消息,找到一个不是异步的消息退出 //为什么不处理这个barrier?barrier 就是一个时间界限,且没有Handler,消息队列就是按时间排序的,处理到了当前这个barrier消息,说明时间满足 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 { //如果时间满足,就是这个消息了,返回这个消息给loop // 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; }
// 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.
// pendingIdleHandlerCount = -1 标记没有被改。有空闲了,处理IdleHandler if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } //居然没有IdleHandler?那就可以休息了 if (pendingIdleHandlerCount <= 0) { // No idle handlers to run. Loop and wait some more. //标记我要休息了,发送消息的时候,可以判断是否需要唤醒我 mBlocked = true; // 直接continue ,在上面的 nativePollOnce(ptr, nextPollTimeoutMillis)就是睡眠了 continue; }
// 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
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. //在处理IdleHandler的过程中,没有睡眠,可能有新的消息来了,不能睡眠 nextPollTimeoutMillis = 0; } }
size_t messageCount = mMessageEnvelopes.size(); // 找到message应该插入的位置i while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { i += 1; }
MessageEnvelope messageEnvelope(uptime, handler, message); mMessageEnvelopes.insertAt(messageEnvelope, i, 1);
// Optimization: If the Looper is currently sending a message, then we can skip // the call to wake() because the next thing the Looper will do after processing // messages is to decide when the next wakeup time should be. In fact, it does // not even matter whether this code is running on the Looper thread. // 如果当前正在发送消息,那么不再调用wake(),直接返回 if (mSendingMessage) { return; } } // release lock // 释放锁 // Wake the poll loop only when we enqueue a new message at the head. // 当消息加入到消息队列的头部时,需要唤醒poll循环 if (i == 0) { wake(); } }
If there is no message, it means that no updates are required. All of our code is just a callback, such as Application onCreate, Activit onCreate, BroadcastReceiver onReceive.
All update callbacks are caused by the message, and these messages are from the system services, such as ActivityManagerService, InputManagerService, WindowMangerService. If you need to update the UI, the android service will send a message to the loop via the IPC.
// Adjust the timeout based on when the next message is due. if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime); if (messageTimeoutMillis >= 0 && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) { timeoutMillis = messageTimeoutMillis; } #if DEBUG_POLL_AND_WAKE ALOGD("%p ~ pollOnce - next message in %" PRId64 "ns, adjusted timeout: timeoutMillis=%d", this, mNextMessageUptime - now, timeoutMillis); #endif }
// Poll. int result = POLL_WAKE; mResponses.clear(); mResponseIndex = 0;
// We are about to idle. // 即将处于idle状态 mPolling = true; // fd最大的个数是16 structepoll_eventeventItems[EPOLL_MAX_EVENTS]; // 等待时间发生或者超时,在nativeWake()方法,向管道写端写入字符,则方法会返回。 int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
// Rebuild epoll set if needed. // 如果需要,重建epoll if (mEpollRebuildRequired) { mEpollRebuildRequired = false; // epoll重建,直接跳转到Done rebuildEpollLocked(); goto Done; }
// Check for poll error. if (eventCount < 0) { if (errno == EINTR) { goto Done; } ALOGW("Poll failed with an unexpected error, errno=%d", errno); // epoll事件个数小于0,发生错误,直接跳转Done result = POLL_ERROR; goto Done; }
// Check for poll timeout. //如果需要,重建epoll if (eventCount == 0) { //epoll事件个数等于0,发生超时,直接跳转Done #if DEBUG_POLL_AND_WAKE ALOGD("%p ~ pollOnce - timeout", this); #endif result = POLL_TIMEOUT; goto Done; }
// Handle all events. #if DEBUG_POLL_AND_WAKE ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); #endif // 循环处理所有的事件 for (int i = 0; i < eventCount; i++) { int fd = eventItems[i].data.fd; uint32_t epollEvents = eventItems[i].events; //首先处理mWakeEventFd if (fd == mWakeEventFd) { //如果是唤醒mWakeEventFd有反应 if (epollEvents & EPOLLIN) { /**重点代码*/ // 已经唤醒了,则读取并清空管道数据 awoken(); // 该函数内部就是read,从而使FD可读状态被清除 } else { ALOGW("Ignoring unexpected epoll events 0x%x on wake event fd.", epollEvents); } } else { // 其他input fd处理,其实就是将活动放入response队列,等待处理 ssize_t requestIndex = mRequests.indexOfKey(fd); if (requestIndex >= 0) { int events = 0; if (epollEvents & EPOLLIN) events |= EVENT_INPUT; if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT; if (epollEvents & EPOLLERR) events |= EVENT_ERROR; if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP; // 处理request,生成对应的response对象,push到响应数组 pushResponse(events, mRequests.valueAt(requestIndex)); } else { ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is " "no longer registered.", epollEvents, fd); } } } Done: ; // Invoke pending message callbacks. // 再处理Native的Message,调用相应回调方法 mNextMessageUptime = LLONG_MAX; while (mMessageEnvelopes.size() != 0) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); if (messageEnvelope.uptime <= now) { // Remove the envelope from the list. // We keep a strong reference to the handler until the call to handleMessage // finishes. Then we drop it so that the handler can be deleted *before* // we reacquire our lock. { // obtain handler sp<MessageHandler> handler = messageEnvelope.handler; Message message = messageEnvelope.message; mMessageEnvelopes.removeAt(0); mSendingMessage = true; // 释放锁 mLock.unlock();
#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", this, handler.get(), message.what); #endif // 处理消息事件 handler->handleMessage(message); } // release handler // 请求锁 mLock.lock(); mSendingMessage = false; // 发生回调 result = POLL_CALLBACK; } else { // The last message left at the head of the queue determines the next wakeup time. mNextMessageUptime = messageEnvelope.uptime; break; } }
// Release lock. // 释放锁 mLock.unlock();
// Invoke all response callbacks. // 处理带有Callback()方法的response事件,执行Response相应的回调方法 for (size_t i = 0; i < mResponses.size(); i++) { Response& response = mResponses.editItemAt(i); if (response.request.ident == POLL_CALLBACK) { int fd = response.request.fd; int events = response.events; void* data = response.request.data; #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", this, response.request.callback.get(), fd, events, data); #endif // Invoke the callback. Note that the file descriptor may be closed by // the callback (and potentially even reused) before the function returns so // we need to be a little careful when removing the file descriptor afterwards. // 处理请求的回调方法 int callbackResult = response.request.callback->handleEvent(fd, events, data); if (callbackResult == 0) { // 移除fd removeFd(fd, response.request.seq); }
// Clear the callback reference in the response structure promptly because we // will not clear the response vector itself until the next poll. // 清除response引用的回调方法 response.request.callback.clear(); // 发生回调 result = POLL_CALLBACK; } } return result; }