Android 触发 ANR 对应的主线程阻塞毫秒时长是多少?
Android ANR触发超时时长相关问题解答
1. 基础默认超时阈值
ANR的触发阈值没有全场景统一的固定值,AOSP源码中针对不同事件场景的默认阈值如下:
- 输入事件(按键、触摸等用户交互事件):5000毫秒(5秒)
- 前台动态注册广播:10000毫秒(10秒)
- 静态注册/后台广播:60000毫秒(60秒)
- 前台Service生命周期回调:20000毫秒(20秒)
- 后台Service生命周期回调:200000毫秒(200秒)
上述仅为原生系统的默认值,实际阈值会受厂商定制ROM修改、系统版本迭代、设备运行时负载影响,部分厂商会为了提升系统响应表现缩短对应阈值,系统高负载下超时判定也可能出现延迟。
2. 能否通过运行时检查全局变量直接获取?
普通第三方应用无法直接通过读取全局变量的方式获取对应阈值:
- 所有ANR阈值常量定义在系统服务(ActivityManagerService、InputManagerService)内部,属于未对外开放的隐藏API,仅系统进程有权限访问
- 如果你拥有设备Root权限或者在做ROM定制开发,可以通过执行shell命令
dumpsys activity settings从输出结果中查询到当前系统对应的各类ANR阈值配置,普通应用无权限读取该命令的输出内容
3. ANR判定逻辑
没有通用的ANR超时计算公式,判定逻辑和事件场景强绑定,核心流程如下:
- 系统服务在向应用主线程分发对应事件(输入事件、广播、Service生命周期回调等)时,会同时在系统的消息队列中插入一条对应时长的延时ANR触发消息
- 如果应用主线程在阈值时间内完成了事件处理,系统会主动将对应延时ANR消息从队列中移除,不会触发ANR
- 如果到达阈值时长后,该延时ANR消息还未被移除,说明主线程仍处于阻塞状态未完成事件处理,系统就会触发ANR流程,弹出ANR提示框并生成对应的trace日志
注意:实际触发ANR的阻塞时长可能略高于默认阈值,若系统资源占用过高、系统消息队列调度延迟,延时ANR消息本身的执行也会被延后,因此实际触发时间会有小范围波动。
内容的提问来源于stack exchange,提问作者Nerdy Bunz
相关产品推荐
相关产品推荐

