- 什么是 ANR
- ANR 产生的原因
- ANR 出现流程分析
- 发生 ANR 如何定位
- 如何避免和解决 ANR
附 Google 官网说明链接:Keeping your app responsive
1. 什么是 ANR
- ANR:Application Not Responding,即应用无响应
- 为用户在主线程长时间被阻塞
- Android 系统自身提供的一种检测机制
-> ANR 的类型
ANR 一般有三种类型:
- KeyDispatchTimeout(5秒超时) – 主要类型按键或触摸事件在特定时间内无响应
- BroadCastTimeout(10秒超时) – 一个广播接收者流程没有在 10 秒之内完成
自定义修改按键响应超时时间
在 frameworks/base/ 下的 ActivityManagerService.java 中定义了具体的超时时间,默认为 5 秒
// How long we wait until we timeout on key dispatching.
static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
2 ANR 产生的原因
超时时间的计数一般是从按键分发给 APP 开始。超时的原因一般有两种:
- 当前的事件没有机会得到处理(即 UI 线程正在处理前一个事件,没有及时的完成或者 looper 因为某种原因阻塞住了)
- 当前的事件正在处理,但是没有及时完成
需要满足的条件:
- 主线程:只有应用的主线程响应超时才会导致 ANR
- 超时时间(Timeout):导致 ANR 的原因不同,系统限定的时间也不同,但只要超过时间上限,系统就会发出 Signal 3,产生 ANR
- 输入操作/特定操作:输入操作指的是按键、触屏等操作,特定操作指的是广播、服务中执行耗时操作等
下面总结了几点常见的引起 ANR 的情况:
1. 应用程序自身引起的
例如,主线程阻塞(block)、挂起、死锁、死循环、执行耗时操作等
2. 其他应用进程引起的
例如,其他进程的 CPU 占用率过高、某一时刻系统 CPU 负载过高等,
都会导致当前进程无法抢到 CPU 时间片
3. IO wait
文件读写耗时较久,占用 CPU 时间片较长,导致 ANR
小技巧:如果你在解决其他问题时也需要查看 Java 进程中各个线程的函数堆栈信息,就可以使用向目标进程发送 SIGNAL_QUIT(3),它并不会让进程真正退出。
3. ANR 出现流程分析
1. 输入时间响应超时导致 ANR 流程
在系统输入管理服务进程(InputManagerS