定位 ANR
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 负荷过多,导致我方程序不要不要的)