Android ANR流程分析
ANR的原因
- 后台Service执行超过20s
- 前台Service执行超过10s
- 按键或触摸事件超过5s
- 前台广播超过10s
- 后台广播超过60s
- ContentProvider超时
系统针对这些场景都有各自的ANR监控机制
原理分析
Service
ANR的监控是在ActiveServices#realStartServiceLocked#bumpServiceExecutingLocked#scheduleServiceTimeoutLocked
建立的
从上图能看出Service启动的时候会给AMS发送一个延时消息,如果service执行完成,那么会移除这个消息,否则这个消息执行serviceTimeout
这里就会弹出ANR
的弹窗
Input
当输入事件处理时间超过5s会产生ANR
从图中可以看到内核将原始事件写入到设备节点中,InputReader
在自己的线程中不断地从EventHub
中提取输入事件,加工处理后放到InputDispatcher
的派发队列中,然后InputDispatcher
将事件派发到合适的窗口。窗口再将这些事件交由ViewRootImpl
处理。InputDispatcher
和窗口之间的跨进程通信主要是通过InputChannel
来完成。
图中findFocusedWindowTargetsLocked()方法会调用checkWindowReadyForMoreInputLocked();该方法检查窗口是否有能力再接收新的输入事件;可能会有一系列的场景阻碍事件的继续派发。
窗口处于paused状态,不能处理输入事件(“Waiting because the [targetType] window is paused.”)
窗口还未向InputDispatcher注册,无法将事件派发到窗口(“Waiting because the [targetType] window’s input channel is not registered with the input dispatcher. The window may be in the process of being removed.”)
窗口和InputDispatcher的连接已经中断,即InputChannel不能正常工作(“Waiting because the [targetType] window’s input connection is [status]. The window may be in the process of being removed.”)
InputChannel已经饱和,不能再处理新的事件(“Waiting because the [targetType] window’s input channel is full. Outbound queue length: %d. Wait queue length: %d.”)
对于按键类型(KeyEvent)的输入事件,需要等待上一个事件处理完毕(“Waiting to send key event because the [targetType] window has not finished processing all of the input events that were previously delivered to it. Outbound queue length: %d. Wait queue length: %d.”)
对于触摸类型(TouchEvent)的输入事件,可以立即派发到当前的窗口,因为TouchEvent都是发生在用户当前可见的窗口。但有一种情况, 如果当前应用由于队列有太多的输入事件等待派发,导致发生了ANR,那TouchEvent事件就需要排队等待派发。
(“Waiting to send non-key event because the %s window has not finished processing certain input events that were delivered to it over %0.1fms ago. Wait queue length: %d. Wait queue head age: %0.1fms.”)
Activity.onCreate执行耗时操作,不管用户如何操作都不会发生ANR,因为输入事件相关监听机制还没有建立起来;InputChannel通道还没有建立。这时是不会响应输入事件,InputDispatcher还不能事件发送到应用窗口,ANR监听机制也还没有建立,所以此时是不会报告ANR的。
Boradcast(广播)
针对广播而言,只有有序广播有超时监控机制,无序广播没有。监控机制依然是采用延时message的形式。
应用层如何判定ANR
WatchDog机制
定时向主线程发送信号
监听SIGNALQUIT信号
向系统注册该信号