Android ANR

什么是ANR

ANR(Application Not Responding)就是通常我们在Andrid上遇到的程序无法响应问题。

如果APP的UI线程被长时间阻塞,就会触发ANR错误,如果我们的应用在前台运行,那么系统就会弹出对话框提示用户,允许用户强制结束程序。

如果应用在后台运行,默认不会弹出对话框;当然,我们也可以在系统设置中的开发者选项中,设置允许后台允许的程序也弹出ANR对话框。

ANR的触发

ANR是怎么产生的呢?

Android应用在UI线程(也叫主线程)中进行事件的分发处理、UI的刷新。当UI线程被阻塞,导致长时间无法处理用户输入或页面绘制,就会造成ANR,给用户的感知就是应用仿佛卡死了一般。

ANR的触发条件如下:

  • 应用有activity在前台运行时,在5秒钟内无法对用户的输入(例如按键或触摸事件)或广播(BroadcastReceiver),做出处理
  • 应用没有前台运行的activity时,如果广播(BroadcastReceiver)没有在一定时间内执行结束(官方文档没有给出具体时间)

Android vitals

Google提供了Android vitals工具来辅助提升应用的性能、稳定性等,遗憾的是需要Google Play框架的支持,这里暂时就不多介绍。

ANR的诊断

下面是一些通常的ANR产生的原因,我们可以沿着这些途径来诊断ANR:

  1. 在主线程中做了涉及IO的耗时操作
  2. 在主线程中做了耗时的大量计算工作
  3. 在主线程中使用了同步的binder跨进程调用,被调用的进程长时间未返回
  4. 在主线程中使用synchronized加锁,而锁已经被其它线程持有并长时间未释放
  5. 主线程和其它线程产生了死锁,可能是自身进程内产生的死锁,也可能是binder调用产生的死锁。

诊断技术

严格模式(Strict mode)

开启严格模式,能够辅助我们在开发阶段发现主线程IO等情况。我们可以在应用层级内或activity层级内开启严格模式。

开启后台ANR对话框

应用在后台运行时,默认不会弹出ANR对话框。我们也可以在系统设置中的开发者选项中,设置允许后台允许的程序也弹出ANR对话框,这样广播处理超时后就会弹出ANR提醒用户。

trace文件

Android在发生ANR的时候,会将相关信息记录到手机上。旧版本的Android会记录到/data/anr/traces.txt文件中,新版本Android系统会记录多个文件:/data/anr/anr_*。通过adb工具将文件取出分析:

$ adb pull /data/anr/<filename>

参考

ANRs



—  我的个人空间 |   —