ANR 是什么
ANR 全称 Application No Response;
Android 设计 ANR 的用意,是系统通过与之交互的组件(Activity,Service,Receiver,Provider)以及用户交互(InputEvent)进行超时监控,
以判断应用进程(主线程)是否存在卡死或响应过慢的问题。
组件超时
系统在通过 Binder 通信向应用进程发送组件消息过 input 事件时,在 AMS 或 input 服务端同时设置一个异步超时监控。
类型 | Timeout(s) | 是否弹窗提示 | 备注 |
---|---|---|---|
Activity | 10 | 提示 | Activity切换时会设置 Timeout |
Broadcast Receiver | 10,60 | 无感知场景不会提示 | |
Service | 20 | 无感知场景不会提示 | 创建 Service 时会设置 Timeout |
ContentProvider | 10 | 无感知场景不会提示 | 创建 provider 时会设置 Timeout |
Input Event | 5 | 提示 | 厂商或平台商会调整此阈值,如8s |
Finalizer | 10 | Crash |
Broadcast 超时原理
广播分为无序广播和有序广播,同时又有前台广播和后台广播之分。系统只针对有序广播设置超时监控机制,并根据前台广播和后台广播的类型决定了超时时长。
后台广播超时时长为60s,前台广播超时时长为10s。
无序广播
对于无序广播,系统在收集所有接收者之后一次性全部发送完毕。无序广播没有设置超时监听机制,一次性发送给所有接收者,对于应用侧何时接收和响应完全不关心。有序广播
在系统 AMS 服务中,BroadcastQueue 获取当前正在发送的广播消息,并取出下一个广播接收者,更新发送时间戳,以此时间计算并设置超时时间(系统在此进行了
一些优化处理,以避免每次广播正常接收后,都需要取消超时监控然后又重新设置,而是采用一种对齐的方式进行复用)。最后将该广播发送给接收者,接收到客户端的
完成通知后,再发送下一个。
在客户端进程中,Binder 线程接收到 AMS 服务发送过来的广播消息之后,会将此消息封装成一个 Message,然后将 Message 发送到主线程消息队列(插入到消息队列当
前时间节点的位置,也正是基于此设计导致较多消息调度及时性的问题)。
正常情况下,很多广播请求都会在客户端及时响应,然后通知到系统 AMS 服务取消本次超时监控。但是在部分业务场景或系统场景异常到情况下,发送到广播未及时调度,
没有及时通知到系统服务,便会在系统服务侧触发超时,判定应用进程响应超时。