引起 ANR 的原因:

  • 当 Activity 在前台时,在 5S 内没有响应触摸事件,或者 BroadcastReceiver 事件
  • 当 Activity 后台运行时, BroadcastReceiveronReceive() 函数在特定时间内没有执行完

常见场景:

  • 主线程执行耗时操作,比如数据库操作,I/O操作
  • 主线程等待子线程释放锁,导致无法及时响应用户的操作事件
  • 主线程上进行长时间的计算
  • 主线程通过 Binder 进行进程间通讯,其他进程长时间不返回结果

严格模式

使用严格模式可以在开发应用程序时在主线程上查找意外的I / O操作。可以在 ApplicationActivity 级别使用严格模式,配置方法:

1
2
3
4
5
6
7
8
9
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build())
StrictMode.setVmPolicy(StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.penaltyDeath()
.build())

当检测到违反规定的操作时,就会在 logcat 中打印日志

开启后台 ANR Dialog

当程序在后台运行时,有时候并不会弹出 ANR 弹窗,此时需要在开发者选项中启用显示所有“应用程序无响应”选项

BlockCanary

BlockCanary 可以有效监控主线程上各种卡慢问题,定位问题并避免出现 ANR,具体使用方法参考官方文档

traces 文件

每次 ANR 都会生成一个 /data/anr/traces.txt 文件,可以根据该文件内容分析出来导致 ANR 的原因