ANR相关-Handler
前言
要分析ANR问题,必须先了解Handler的基本原理;
常见的ANR原因包括
A.主线程有耗时操作,如有复杂的layout布局,IO操作等。
B.被Binder对端block
C.被子线程同步锁block
D.Binder被占满导致主线程无法和SystemServer通信
E.得不到系统资源(CPU/RAM/IO)
就以Service处理超时为例,一般我们对Service执行一个操作时,都是通过AMS来对Service实例进行操作,每一个操作前都会执行bumpServiceExecutingLocked函数
2121 bumpServiceExecutingLocked(r, execInFg, "bind");
2558 bumpServiceExecutingLocked(r, execInFg, "create");
2682 bumpServiceExecutingLocked(r, execInFg, "start");
2808 bumpServiceExecutingLocked(r, false, "bring down unbind");
2908 bumpServiceExecutingLocked(r, false, "destroy");
3004 bumpServiceExecutingLocked(s, false, "unbind");
其中会调用scheduleServiceTimeoutLocked(r.app),其中会向AMS的ActivityManager线程handler发送一个消息
mHandler = new MainHandler(mHandlerThread.getLooper());
37574 msg.obj = proc;
3575 mAm.mHandler.sendMessageDelayed(msg,
3576 proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
Message中包含Service的宿主进程,也是将来可能发生ANR的进程,这个Message进入到system_server的主线程Handler中,什么时候取消呢?
当Service执行完AMS要求的操作时取消,以sendServiceArgsLocked为例:
ActiveServices#sendServiceArgsLocked
r.app.thread.scheduleServiceArgs(r, slice);
Service所在进程的一个binder线程响应scheduleServiceArgs接口
ActivityThread#scheduleServiceArgs
890 public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
891 List<ServiceStartArgs> list = args.getList();
892
893 for (int i = 0; i < list.size(); i++) {
894 ServiceStartArgs ssa = list.get(i);
895 ServiceArgsData s = new ServiceArgsData();
896 s.token = token;
897 s.taskRemoved = ssa.taskRemoved;
898 s.startId = ssa.startId;
899 s.flags = ssa.flags;
900 s.args = ssa.args;
901
902 sendMessage(H.SERVICE_ARGS, s);
903 }
904 }
Service宿主进程的binder线程向其主线程handler(ActivityThread$H)发送消息,消息执行完后,就会call binder AMS中的serviceDoneExecuting接口
ActivityThread#handleServiceArgs
3509 if (!data.taskRemoved) {
3510 res = s.onStartCommand(data.args, data.flags, data.startId); //调用onStartCommand
3511 } else {
3512 s.onTaskRemoved(data.args); //调用onTaskRemoved,用于最近任务中划掉进程的Task时被调用
3513 res = Service.START_TASK_REMOVED_COMPLETE;
3514 }
//在通知AMS消息处理完成前,现完成本地等待处理的任务
//这里与启动BroadcastReceiver对应进程的情况相似
//进程可能是由于创建Service才被启动的,Service处理完毕后,AMS可能进行进程管理
//杀死Service对应进程,因此先确保工作做完
3516 if(!ActivityThreadInjector.isPersistent(mBoundApplication)) {
3517 QueuedWork.waitToFinish();
3518 }
3519 // QueuedWork.waitToFinish(); //等待本地QueuedWork处理完成,再进行清理工作 //参考https://jira.n.xiaomi.com/browse/MIUI-860168 QueuedWork类似任务队列
3520 // END
3521 try {
3522 ActivityManager.getService().serviceDoneExecuting(
3523 data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); //通知AMS ServiceRecord相关结果,执行收尾工作,本次的type为SERVICE_DONE_EXECUTING_START,res为onStartCommand的返回值,描述了在系统的杀死事件中,系统应该如何继续这个服务的值,参考https://blog.csdn.net/taki_dsm/article/details/8865913 https://blog.csdn.net/zjws23786/article/details/51800929 return值由服务的需求自己指定
3524 } catch (RemoteException e) {
3525 throw e.rethrowFromSystemServer();
3526 }
当Service所在进程的主线程执行完相应的操作时,会调用AMS中的serviceDoneExecuting接口
3378 ActivityManager.getService().serviceDoneExecuting(
3379 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
system_server找一个空闲的binder线程执行serviceDoneExecuting操作,最终会调用到
mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
为system_server的主线程Handler移除这个Service超时消息,则不会发生ANR
Handler#removeMessages
748 /**
749 * Remove any pending posts of messages with code 'what' that are in the
750 * message queue.
751 */
752 public final void removeMessages(int what) {
753 mQueue.removeMessages(this, what, null);
754 }
MessageQueue#removeMessages
将MessageQueue中的所有what消息都移除
644 void removeMessages(Handler h, int what, Object object) {
645 if (h == null) {
646 return;
647 }
648
649 synchronized (this) {
650 Message p = mMessages;
//消息队列头消息
651
652 // Remove all messages at front.
//针对头结点就是what的情况,将前面的所有what都移除
653 while (p != null && p.target == h && p.what == what
654 && (object == null || p.obj == object)) {
655 Message n = p.next;
656 mMessages = n;
657 p.recycleUnchecked();
658 p = n;
659 }
660
661 // Remove all messages after front.
//将中间的所有what都移除,适用于what消息夹杂在中间的情况
662 while (p != null) {
663 Message n = p.next;
664 if (n != null) {
665 if (n.target == h && n.what == what
666 && (object == null || n.obj == object)) {
667 Message nn = n.next;
668 n.recycleUnchecked();
669 p.next = nn;
670 continue;
671 }
672 }
673 p = n;
674 }
675 }
676 }
Handler相关
从上面的说明可以发现,对于Service而言,如果Service所在进程的主线程没有执行完相应的Message,没有及时返回结果,那么system_server就会认为Service进程的主线程耗时过长,因此就会使Service所在进程发生ANR;
那么其实我这里就可以想到三种情况
1.确实是Service宿主进程主线程Handler执行这个Service相关操作的Message耗时过长
2.Service宿主进程主线程Handler执行前面的Message耗时过长,导致这个Service操作相关消息迟迟不能被取出执行
(注意,一个线程对应一个Looper,一个MessageQueue,但不止一个Handler,线程可以创建多个Handler可以共用一个Looper,Looper.loop不断取出MessageQueue中的消息,发送给对应的Handler进行执行)
3.执行完这个Message需要向AMS回调serviceDoneExecuting,那么
3.1 可能system_server找不到空闲的binder线程
3.2 找到了空闲binder线程,但其需要的AMS锁被其他binder线程持有
同时,可以发现ANR原理的分析需要Handler的相关知识,本文重点介绍下
Handler的构造
109 /**
110 * Default constructor associates this handler with the {@link Looper} for the
111 * current thread.
112 *
113 * If this thread does not have a looper, this handler won't be able to receive messages
114 * so an exception is thrown.
115 */
116 public Handler() {
117 this(null, false);
118 }
将当前线程中的looper赋给final Looper mLooper
一个线程只有一个looper,但不一定只有一个Handler,可以写多个Handler用来处理不同的Message,looper对决定将消息交给哪个Handler去处理;当一个消息处理完后处理下一个;
比如,一个进程的主线程Handler,除了ActivityThread$H之外,还可以自己定义,如:
6public class MainHandler {
7 private static final Handler sMainHandler = new Handler(Looper.getMainLooper()); //为进程的主线程创建一个MainHandler
8
9 private MainHandler() {}
10
11 public static Handler getMainHandler() {
12 return sMainHandler;
13 }
14}
22 public static void show(final String text) {
23 Handler handler = new Handler(Looper.getMainLooper());
//MainHandler.post (包装成消息发送,执行)
24 handler.post(new Runnable() {
25 @Override
26 public void run() {
27 if (sToast == null) {
28 sToast = Toast.makeText(FileExplorerApplication.getInstance().getApplicationContext(), text, Toast.LENGTH_SHORT);
29 } else {
30 sToast.setText(text);
31 sToast.setDuration(Toast.LENGTH_SHORT);
32 }
33
34 sToast.show();
35 }
36 });
37 }
getMainLooper的实现如下:
123 /**
124 * Returns the application's main looper, which lives in the main thread of the application.
125 */
126 public static Looper getMainLooper() {
127 synchronized (Looper.class) {
128 return sMainLooper;
129 }
130 }
sMainLooper在Looper.java中的prepareMainLooper中被赋值
103 /**
104 * Initialize the current thread as a looper, marking it as an
105 * application's main looper. The main looper for your application
106 * is created by the Android environment, so you should never need
107 * to call this function yourself. See also: {@link #prepare()}
108 */
109 public static void prepareMainLooper() {
110 prepare(false);
111 synchronized (Looper.class) {
112 if (sMainLooper != null) {
113 throw new IllegalStateException("The main Looper has already been prepared.");
114 }
115 sMainLooper = myLooper();
120 }
121 }
在ActivityThread中被调用
6760 public static void main(String[] args) {
...
6778
6779 Looper.prepareMainLooper();
...
6809 }
Handler传递消息
343 /**
344 * Causes the Runnable r to be added to the message queue.
345 * The runnable will be run on the thread to which this handler is
346 * attached.
347 *
348 * @param r The Runnable that will be executed.
349 *
350 * @return Returns true if the Runnable was successfully placed in to the
351 * message queue. Returns false on failure, usually because the
352 * looper processing the message queue is exiting.
353 */
354 public final boolean post(Runnable r)
355 {
356 return sendMessageDelayed(getPostMessage(r), 0);
357 }
778 private static Message getPostMessage(Runnable r) {
779 Message m = Message.obtain();
780 m.callback = r; //post(Runnable r) 相当于也是创建消息,将消息的Callback赋值
781 return m;
782 }
消息入队的操作
frameworks/base/core/java/android/os/Handler.java
689 public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
690 MessageQueue queue = mQueue;
691 if (queue == null) {
692 RuntimeException e = new RuntimeException(
693 this + " sendMessageAtTime() called with no mQueue");
694 Log.w("Looper", e.getMessage(), e);
695 return false;
696 }
697 return enqueueMessage(queue, msg, uptimeMillis);
698 }
740 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
741 msg.target = this;
742 if (mAsynchronous) {
743 msg.setAsynchronous(true);
744 }
745 return queue.enqueueMessage(msg, uptimeMillis);
746 }
frameworks/base/core/java/android/os/MessageQueue.java
boolean enqueueMessage(Message msg, long when) {
537 if (msg.target == null) {
538 throw new IllegalArgumentException("Message must have a target.");
539 }
540 if (msg.isInUse()) {
541 throw new IllegalStateException(msg + " This message is already in use.");
542 }
543
544 synchronized (this) {
545 if (mQuitting) {
546 IllegalStateException e = new IllegalStateException(
547 msg.target + " sending message to a Handler on a dead thread");
548 Log.w(TAG, e.getMessage(), e);
549 msg.recycle();
550 return false;
551 }
552
553 msg.markInUse();
554 msg.when = when;
555 Message p = mMessages; //mMessages这个值代表MessageQueue的队头,可以为null,为null时代表当前队列为空
556 boolean needWake;
557 if (p == null || when == 0 || when < p.when) {
558 // New head, wake up the event queue if blocked.
//1.当前队列为空 2.或者Message需要立即执行 3.Message的执行时间比当前队列的头Message的执行时间还要前
559 msg.next = p;
560 mMessages = msg; //将入队Message置为头节点
561 needWake = mBlocked; //如果入队前队列为空,或者入队Message为队头,可能需要唤醒queue,根据mBlocked属性决定
562 } else {
563 // Inserted within the middle of the queue. Usually we don't have to wake
564 // up the event queue unless there is a barrier at the head of the queue
565 // and the message is the earliest asynchronous message in the queue.
566 needWake = mBlocked && p.target == null && msg.isAsynchronous(); //如果当前队列卡住,队头为屏障消息,则只有异步消息能唤醒队列
567 Message prev;
568 for (;;) {
569 prev = p; //prev保存队头
570 p = p.next;
571 if (p == null || when < p.when) {
//找到了Message合适的插入位置就停下来
572 break;
573 }
574 if (needWake && p.isAsynchronous()) {
575 needWake = false;
576 }
577 }
578 msg.next = p; // invariant: p == prev.next
579 prev.next = msg; //插入到适当位置
//将msg插入到prev和p之间
580 }
581
582 // We can assume mPtr != 0 because mQuitting is false.
583 if (needWake) {
584 nativeWake(mPtr); //唤醒队列
585 }
586 }
587 return true;
588 }
Handler执行消息
Looper.loop 线程的loop循环执行
Looper.loop
137 public static void loop() {
138 final Looper me = myLooper();
...
142 final MessageQueue queue = me.mQueue;
143
...
158
159 for (;;) {
160 Message msg = queue.next(); // might block //从队列中取出消息
...
192 try {
193 msg.target.dispatchMessage(msg); //找到消息后,调用消息对应的Handler的dispatchMessage
194 dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
195 } finally {
196 if (traceTag != 0) {
197 Trace.traceEnd(traceTag);
198 }
199 }
...
233 msg.recycleUnchecked(); //消息回收
234 }
235 }
首先看取出的消息如何处理
96 public void dispatchMessage(Message msg) {
97 if (msg.callback != null) {
98 handleCallback(msg);
99 } else {
100 if (mCallback != null) {
101 if (mCallback.handleMessage(msg)) {
102 return;
103 }
104 }
105 handleMessage(msg);
106 }
107 }
dispatch Message处理消息也有3种情况
情况1:消息中含有Callback,一般是通过post传递的Runnable对象被封装成的消息;
相当于只要Runnable被当作消息取出来了,就会执行其run方法
791 private static void handleCallback(Message message) {
792 message.callback.run();
793 }
情况2:Handler初始化时赋值了一个Callback
130 public Handler(Callback callback) {
131 this(callback, false);
132 }
示例:
68 @TargetApi(Build.VERSION_CODES.CUPCAKE)
69 public void execute() {
70 mHandler = new Handler(new Handler.Callback(){
71 @Override
72 public boolean handleMessage(Message msg) {
73 switch (msg.what) {
74 case REQUEST_DATA_CACHEED: {
75 if (mListener != null) mListener.onCacheGot(mResponse);
76 break;
77 }
78 case REQUEST_DATA_LOADED: {
79 if (mListener != null) mListener.onDataStatusChanged(mResponse);
80 break;
81 }
82 default:
83 break;
84 }
85 return true;
86 }
87 });
88 ThreadDispatcher.getInstance().runInBackgroud(this);
89 }
则消息被从队列中取出时,会执行Handler中的mCallback的handleMessage方法
情况3:消息和Handler都没有被赋值Callback,因此就需要调用Handler重载的handleMessage方法
示例:
111 private class MainHandler extends Handler {
112 private static final int MSG_INFO_UPDATED = 1;
113
114 @Override
115 public void handleMessage(Message msg) {
116 switch (msg.what) {
117 case MSG_INFO_UPDATED:
118 mCallback.onExtraInfoUpdated();
119 break;
120 }
121 }
122 }
Looper取出MessageQueue中的消息
最后看一下Message如何从消息队列中取出:
315 Message next() {
316 // Return here if the message loop has already quit and been disposed.
317 // This can happen if the application tries to restart a looper after quit
318 // which is not supported.
319 final long ptr = mPtr;
320 if (ptr == 0) {
321 return null;
322 }
323
324 int pendingIdleHandlerCount = -1; // -1 only during first iteration
325 int nextPollTimeoutMillis = 0;
326 for (;;) {
327 if (nextPollTimeoutMillis != 0) {
328 Binder.flushPendingCommands();
329 }
330
331 nativePollOnce(ptr, nextPollTimeoutMillis);
//nextPollTimeoutMillis 队列为空时一直等待,直到被唤醒(下一个Message入队)
332
333 synchronized (this) {
334 // Try to retrieve the next message. Return if found.
335 final long now = SystemClock.uptimeMillis();
336 Message prevMsg = null;
337 Message msg = mMessages; //链表头
338 if (msg != null && msg.target == null) {
//如果链表头是一个屏障消息
339 // Stalled by a barrier. Find the next asynchronous message in the queue. //消息屏障(对于非异步消息而言,当有消息屏障时,岂不到唤醒队列的作用)
340 do {
//那么msg只能找到异步消息
341 prevMsg = msg;
342 msg = msg.next;
343 } while (msg != null && !msg.isAsynchronous());
344 }
//如果没有屏障消息,此时msg还是队头Message
345 if (msg != null) {
346 if (now < msg.when) {
//当前时间小于队头Message需要执行的时间,还需要再等一段时间
347 // Next message is not ready. Set a timeout to wake up when it is ready.
348 nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
349 } else {
350 // Got a message.
//返回队头Message
351 mBlocked = false; //当可以得到一个Message返回时,将mBlocked置为false,表明此时队列不再阻塞了
352 if (prevMsg != null) {
//针对有屏障的情况,重新组织MessageQueue队列
353 prevMsg.next = msg.next;
354 } else {
//将 mMessages 设为msg.next,这样就可以把队头Message返回
355 mMessages = msg.next;
356 }
//返回要执行的Message
357 msg.next = null;
358 if (DEBUG) Log.v(TAG, "Returning message: " + msg);
359 msg.markInUse();
360 return msg;
361 }
362 } else {
363 // No more messages.
364 nextPollTimeoutMillis = -1;
365 }
366
367 // Process the quit message now that all pending messages have been handled.
368 if (mQuitting) {
369 dispose();
370 return null;
371 }
372
373 // If first time idle, then get the number of idlers to run.
374 // Idle handles only run if the queue is empty or if the first message
375 // in the queue (possibly a barrier) is due to be handled in the future.
376 if (pendingIdleHandlerCount < 0
377 && (mMessages == null || now < mMessages.when)) {
378 pendingIdleHandlerCount = mIdleHandlers.size();
379 }
380 if (pendingIdleHandlerCount <= 0) {
381 // No idle handlers to run. Loop and wait some more.
//除非顺利返回了Message,否则 nextPollTimeoutMillis >0或-1,分别代表首个Message没到时间或队列为空,此时队列阻塞,并进入下一个等待
382 mBlocked = true;
383 continue;
384 }
385
386 if (mPendingIdleHandlers == null) {
387 mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
388 }
389 mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
390 }
391
392 // Run the idle handlers.
393 // We only ever reach this code block during the first iteration.
394 for (int i = 0; i < pendingIdleHandlerCount; i++) {
395 final IdleHandler idler = mPendingIdleHandlers[i];
396 mPendingIdleHandlers[i] = null; // release the reference to the handler
397
398 boolean keep = false;
399 try {
400 keep = idler.queueIdle();
401 } catch (Throwable t) {
402 Log.wtf(TAG, "IdleHandler threw exception", t);
403 }
404
405 if (!keep) {
406 synchronized (this) {
407 mIdleHandlers.remove(idler);
408 }
409 }
410 }
411
412 // Reset the idle handler count to 0 so we do not run them again.
413 pendingIdleHandlerCount = 0;
414
415 // While calling an idle handler, a new message could have been delivered
416 // so go back and look again for a pending message without waiting.
417 nextPollTimeoutMillis = 0;
418 }
419 }
nativePollOnce
frameworks/base/core/jni/android_os_MessageQueue.cpp
212static const JNINativeMethod gMessageQueueMethods[] = {
213 /* name, signature, funcPtr */
...
216 { "nativePollOnce", "(JI)V", (void*)android_os_MessageQueue_nativePollOnce },
217 { "nativeWake", "(J)V", (void*)android_os_MessageQueue_nativeWake },
...
221};
188static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
189 jlong ptr, jint timeoutMillis) {
190 NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
191 nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
192}
107void NativeMessageQueue::pollOnce(JNIEnv* env, jobject pollObj, int timeoutMillis) {
108 mPollEnv = env;
109 mPollObj = pollObj;
110 mLooper->pollOnce(timeoutMillis);
111 mPollObj = NULL;
112 mPollEnv = NULL;
...
119}
/system/core/libutils/Looper.cpp
178int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
179 int result = 0;
180 for (;;) {
181 while (mResponseIndex < mResponses.size()) {
182 const Response& response = mResponses.itemAt(mResponseIndex++);
183 int ident = response.request.ident;
184 if (ident >= 0) {
185 int fd = response.request.fd;
186 int events = response.events;
187 void* data = response.request.data;
188#if DEBUG_POLL_AND_WAKE
189 ALOGD("%p ~ pollOnce - returning signalled identifier %d: "
190 "fd=%d, events=0x%x, data=%p",
191 this, ident, fd, events, data);
192#endif
193 if (outFd != NULL) *outFd = fd;
194 if (outEvents != NULL) *outEvents = events;
195 if (outData != NULL) *outData = data;
196 return ident; //针对回调函数为空的情况,ident值必为一个大于等于0的值
197 }
198 }
199
200 if (result != 0) {
201#if DEBUG_POLL_AND_WAKE
202 ALOGD("%p ~ pollOnce - returning result %d", this, result);
203#endif
204 if (outFd != NULL) *outFd = 0;
205 if (outEvents != NULL) *outEvents = 0;
206 if (outData != NULL) *outData = NULL;
207 return result; //根据pollInner的结果进行处理,实际上是针对设置了回调函数的情况,因为设置了回调函数,所以已经对发生的事件做了处理了,所以,不需要将发生事件的相关信息再返回给调用者了
208 }
209
210 result = pollInner(timeoutMillis);
211 }
212}
214int Looper::pollInner(int timeoutMillis) {
215#if DEBUG_POLL_AND_WAKE
216 ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
217#endif
218
219 // Adjust the timeout based on when the next message is due.
220 if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
221 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
222 int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
223 if (messageTimeoutMillis >= 0
224 && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
225 timeoutMillis = messageTimeoutMillis; //重新计算超时时间
226 }
227#if DEBUG_POLL_AND_WAKE
228 ALOGD("%p ~ pollOnce - next message in %" PRId64 "ns, adjusted timeout: timeoutMillis=%d",
229 this, mNextMessageUptime - now, timeoutMillis);
230#endif
231 }
232
233 // Poll.
234 int result = POLL_WAKE;
235 mResponses.clear();
236 mResponseIndex = 0;
237
238 // We are about to idle.
239 mPolling = true;
240
241 struct epoll_event eventItems[EPOLL_MAX_EVENTS];
242 int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
243
244 // No longer idling.
245 mPolling = false;
246
247 // Acquire lock.
248 mLock.lock();
249
250 // Rebuild epoll set if needed.
251 if (mEpollRebuildRequired) {
252 mEpollRebuildRequired = false;
253 rebuildEpollLocked();
254 goto Done;
255 }
256
257 // Check for poll error.
258 if (eventCount < 0) { //返回值小于零,表示发生错误
259 if (errno == EINTR) {
260 goto Done;
261 }
262 ALOGW("Poll failed with an unexpected error: %s", strerror(errno));
263 result = POLL_ERROR;
264 goto Done;
265 }
266
267 // Check for poll timeout.
268 if (eventCount == 0) { //eventCount为零,表示发生超时,因此直接跳转到Done
269#if DEBUG_POLL_AND_WAKE
270 ALOGD("%p ~ pollOnce - timeout", this);
271#endif
272 result = POLL_TIMEOUT;
273 goto Done;
274 }
275
276 // Handle all events.
277#if DEBUG_POLL_AND_WAKE
278 ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
279#endif
280
281 for (int i = 0; i < eventCount; i++) {
282 int fd = eventItems[i].data.fd;
283 uint32_t epollEvents = eventItems[i].events;
284 if (fd == mWakeEventFd) {
285 if (epollEvents & EPOLLIN) {
//通过wake唤醒队列
286 awoken();
287 } else {
288 ALOGW("Ignoring unexpected epoll events 0x%x on wake event fd.", epollEvents);
289 }
290 } else {
291 ssize_t requestIndex = mRequests.indexOfKey(fd);
292 if (requestIndex >= 0) {
293 int events = 0;
294 if (epollEvents & EPOLLIN) events |= EVENT_INPUT;
295 if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT;
296 if (epollEvents & EPOLLERR) events |= EVENT_ERROR;
297 if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP;
298 pushResponse(events, mRequests.valueAt(requestIndex)); //如果是其他FD发生事件,则根据Request构造Response,并push到Response数组
//当某个监控fd上发生事件后,就会把对应的Request取出来调用。
299 } else {
300 ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
301 "no longer registered.", epollEvents, fd);
302 }
303 }
304 }
305Done: ;
306
307 // Invoke pending message callbacks.
308 mNextMessageUptime = LLONG_MAX;
309 while (mMessageEnvelopes.size() != 0) {
310 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
311 const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
312 if (messageEnvelope.uptime <= now) {
313 // Remove the envelope from the list.
314 // We keep a strong reference to the handler until the call to handleMessage
315 // finishes. Then we drop it so that the handler can be deleted *before*
316 // we reacquire our lock.
317 { // obtain handler
318 sp<MessageHandler> handler = messageEnvelope.handler;
319 Message message = messageEnvelope.message;
320 mMessageEnvelopes.removeAt(0);
321 mSendingMessage = true;
322 mLock.unlock();
323
324#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
325 ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
326 this, handler.get(), message.what);
327#endif
328 handler->handleMessage(message);
329 } // release handler
330
331 mLock.lock();
332 mSendingMessage = false;
333 result = POLL_CALLBACK;
334 } else {
335 // The last message left at the head of the queue determines the next wakeup time.
336 mNextMessageUptime = messageEnvelope.uptime;
337 break;
338 }
339 }
340
341 // Release lock.
342 mLock.unlock();
343
344 // Invoke all response callbacks.
345 for (size_t i = 0; i < mResponses.size(); i++) {
346 Response& response = mResponses.editItemAt(i);
347 if (response.request.ident == POLL_CALLBACK) {
348 int fd = response.request.fd;
349 int events = response.events;
350 void* data = response.request.data;
351#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
352 ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
353 this, response.request.callback.get(), fd, events, data);
354#endif
355 // Invoke the callback. Note that the file descriptor may be closed by
356 // the callback (and potentially even reused) before the function returns so
357 // we need to be a little careful when removing the file descriptor afterwards.
358 int callbackResult = response.request.callback->handleEvent(fd, events, data);//回调其他fd定义的callback
359 if (callbackResult == 0) {
360 removeFd(fd, response.request.seq);
361 }
362
363 // Clear the callback reference in the response structure promptly because we
364 // will not clear the response vector itself until the next poll
365 response.request.callback.clear();
366 result = POLL_CALLBACK;
367 }
368 }
369 return result;
370}
有消息入队时的wake操作,唤醒队列,nativePollOnce不再等待,相当于提醒MessageQueue有消息入队了,但是否现在执行,需要根据消息中的信息,由MessageQueue.next()决定
唤醒操作如下:
enqueueMessage中
583 if (needWake) {
584 nativeWake(mPtr);
585 }
194static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr) {
195 NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
196 nativeMessageQueue->wake();
197}
121void NativeMessageQueue::wake() {
122 mLooper->wake();
123}
398void Looper::wake() {
399#if DEBUG_POLL_AND_WAKE
400 ALOGD("%p ~ wake", this);
401#endif
402
403 uint64_t inc = 1;
404 ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t)));
405 if (nWrite != sizeof(uint64_t)) {
406 if (errno != EAGAIN) {
407 LOG_ALWAYS_FATAL("Could not write wake signal to fd %d: %s",
408 mWakeEventFd, strerror(errno));
409 }
410 }
411}
Looper.loop()中是个for循环,必须等到一个Message执行完了,才有机会回到MessageQueue.next()来查找下一个待执行的Message;所以,前面的Message处理超时,也会造成ANR;关键要找到真正耗时的消息,以及其耗时的原因;
总结
本文主要介绍了android的Handler机制,这对我们理解ANR的原理很有帮助