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 信号

向系统注册该信号