at com.msisuzney.testepoll.MainActivity.dispatchTouchEvent(MainActivity.java:41) at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:402) at android.view.View.dispatchPointerEvent(View.java:12768) at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5274) at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5074) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4589) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4642) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4608) at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4748) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4616) at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4805) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4589) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4642) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4608) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4616) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4589) at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7319) at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7286) at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7247) at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7427) at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:253) at android.os.MessageQueue.nativePollOnce(Native Method) at android.os.MessageQueue.next(MessageQueue.java:332) at android.os.Looper.loop(Looper.java:168) at android.app.ActivityThread.main(ActivityThread.java:6878) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)
对比我们点击一个View时使用Handler机制运行的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
at com.msisuzney.testepoll.MainActivity.click(MainActivity.java:46) at java.lang.reflect.Method.invoke(Native Method) at android.view.View$DeclaredOnClickListener.onClick(View.java:5640) at android.view.View.performClick(View.java:6608) at android.view.View.performClickInternal(View.java:6585) at android.view.View.access$3100(View.java:785) at android.view.View$PerformClick.run(View.java:25921) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:6878) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)
Message next(){ ...... 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; 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 { mMessages = msg.next; } msg.next = null; if (DEBUG) Log.v(TAG, "Returning message: " + msg); msg.markInUse(); return msg; } } else { // No more messages. nextPollTimeoutMillis = -1; } ........ } ....... } }
// Poll. int result = POLL_WAKE; mResponses.clear(); mResponseIndex = 0;
// We are about to idle. mPolling = true;
struct epoll_event eventItems[EPOLL_MAX_EVENTS]; //Java层的nativePollOnce()最终堵在这里等待epoll监听的文件描述符有新的事件通知,返回的是事件的数量 int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis); //一旦走到这里,说明有新的文件描述符通知 // No longer idling. mPolling = false;
// Acquire lock. mLock.lock(); ...... //遍历事件 for (int i = 0; i < eventCount; i++) { const SequenceNumber seq = eventItems[i].data.u64; uint32_t epollEvents = eventItems[i].events; if (seq == WAKE_EVENT_FD_SEQ) { //如果是Handler消息唤醒的,直接读这个写入的字符完事了,因为目的本来就是唤醒主线程,目的已达成,待会执行到外面Java层的死循环会去遍历MessageQueue if (epollEvents & EPOLLIN) { awoken(); } else { ALOGW("Ignoring unexpected epoll events 0x%x on wake event fd.", epollEvents); } } else { //如果是其他文件描述符,那依依遍历它们,然后将它的事件放进mResponses中 const auto& request_it = mRequests.find(seq); if (request_it != mRequests.end()) { const auto& request = request_it->second; 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; mResponses.push({.seq = seq, .events = events, .request = request}); } else { ALOGW("Ignoring unexpected epoll events 0x%x for sequence number %" PRIu64 " that is no longer registered.", epollEvents, seq); } } } .......
// Invoke all response callbacks. 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) { AutoMutex _l(mLock); removeSequenceNumberLocked(response.seq); }
// Clear the callback reference in the response structure promptly because we // will not clear the response vector itself until the next poll. response.request.callback.clear(); result = POLL_CALLBACK; } } return result; }