Android ANR 流程分析
ANR 的原因
- 后台 Service 执行超过 20s
- 前台 Service 执行超过 10s
- 按键或触摸事件超过 5s
- 前台广播超过 10s
- 后台广播超过 60s
- ContentProvider 超时
系统针对这些场景都有各自的 ANR 监控机制
原理分析
Service

service 启动
ANR 的监控是在ActiveServices#realStartServiceLocked#bumpServiceExecutingLocked#scheduleServiceTimeoutLocked
建立的

service anr 时序图
从上图能看出 Service 启动的时候会给 AMS 发送一个延时消息,如果 service 执行完成,那么会移除这个消息,否则这个消息执行 serviceTimeout
这里就会弹出 ANR
的弹窗
Input
当输入事件处理时间超过 5s 会产生 ANR

input 事件系统
从图中可以看到内核将原始事件写入到设备节点中,InputReader
在自己的线程中不断地从 EventHub
中提取输入事件,加工处理后放到 InputDispatcher
的派发队列中,然后 InputDispatcher
将事件派发到合适的窗口。窗口再将这些事件交由 ViewRootImpl
处理。InputDispatcher
和窗口之间的跨进程通信主要是通过 InputChannel
来完成。

input anr 时序图
图中 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 (广播)

broadcast anr 时序图
针对广播而言,只有有序广播有超时监控机制,无序广播没有。监控机制依然是采用延时 message 的形式。
应用层如何判定 ANR
WatchDog 机制
定时向主线程发送信号
监听 SIGNALQUIT 信号
向系统注册该信号