ANR 是 Application Not Responsing 的简称,简而言之,就是安卓系统内置提示用户应用界面没有反应的机制,是用来避免应用界面一直卡顿,增加系统用户友好度的一种方式。

当开发 Android 应用时出现 ANR,Framework 会在弹出 Dialog 的同时 dump 出当前各Thread 的堆栈 保存在 /data/anr/ 目录下命名为 traces.txt,方便开发者分析出 ANR 的 root cause.

造成 ANR 的原因有很多种,基本都是因为在 Main Thread run 任务太久导致阻塞了界面更新造成的,主要有以下几类:

  • Other Timeout:排在最前面,这属于作死操作,比如 Main Thread(UI Thread) 睡它个几十秒 或 其它耗时操作
  • Broadcast Timeout:前台广播执行超过 10s,后台广播执行超过 60s.
  • Service Timeout:前台服务执行超过 20s,后台服务执行超过 200s.
  • Provider Timeout:内容提供者发布超过 10s.
  • Input Timeout:按键触摸事件分发超过 5s.

能够造成 ANR 的前提是任务是在 UI Thread 上执行的,执行什么样的任务主要有以下几点:

  • 执行耗时任务过久,如读取或存储,网络访问文件太耗时.
  • Thread 被阻塞过久,或者干脆出现了死锁.
  • Thread 饥饿,如 Binder Thread 总共 16 个,Binder Main Thread 占有一个,剩余的 15 个工作线程都被占满.
  • CPU 饥饿,负载值过大,虽然程序没毛病,但是任务一直没有来得及更新,(情况很多种,有来自内在和外在的,如外在的某些不良程序,在某些低配手机运行长期获取栈顶应用 CPU 负荷过多,导致我方程序不要不要的)