一、ANR 的定义
ANR 全称 Application Not Responding,意思就是应用程序无响应
二、ANR 产生的原因
1、当前事件没有得到处理,比如 UI 线程正在响应另一事件,当前事件由于某种原因被阻塞了
2、当前的事件正在被处理,但是由于耗时太长没有能够及时完成
三、ANR 产生的本质原因
1、keydispatchtimeout:最常见的一种类型,原因是 view 事件或者触摸事件在 5 秒内未得到及时响应
2、broadcasttimeout:BroadcastReceiver 的 onReceive 函数运行在主线程,并在特定的时间内(10s)无法完成处理
3、servicetimeout:Service 的各个生命周期函数在特定时间内(20s)无法完成响应
四、典型 ANR 场景
1、主线程频繁进行 IO 操作,比如读写文件或者数据库
2、硬件操作如进行调用照相机或者录音等操作
3、多线程操作的死锁,导致主线程等待超时
4、主线程调用 join() 方法、sleep() 方法或者 wait() 方法
5、耗时动画/耗资源行为导致 CPU 负载过重
6、system server 中发生 WatchDog ANR
7、service binader 的数量到达了上限
五、Thread 说明
六、分析思路
1、logcat 抓取日志命令:adb logcat -v time > C:/Users/dd/Desktop/logcat.log
(1)从 logcat 分析:查询关键字:ANR/ANR in com.xxx.xxx
(2)关键字所展示的内容:
导致 ANR 的类名及所在包名,比如:ANR in com.xxx.xxx(com.xxx.xxx/com.xxx.ui.edit.MainActivity)
导致 ANR 的进程名及 ID,比如 PID:10228
ANR 产生的原因 (类型):Reason: Input dispatching timed out
系统中 CPU 使用率的统计信息及某段时间内的变换情况
2、从 trace.txt 文件分析
(1)使用命令获取 trace 文件:adb pull /data/anr/trace.txt
(2)在 trace.txt 文件中可以查看到以下信息:
应用程序包名:Cmd line:com.xxx.xxx
手机的 CPU 架构:ABI:‘arm64’
堆内存信息
手机 Memory 内存信息
(3)主线程日志分析
基本信息:main-线程名称,prio-线程优先级,tid-线程 id,Waiting-线程状态
详细信息:group-线程组名称,sCount-线程被挂起的次数,dsCount-线程被调试器刮起的次数,obj-线程的 Java 对象地址,self-线程本身的 Native 对象地址
线程的调度信息:sysTid-linux 系统中内核线程 id(观察发现主线程的线程号和进程号相同),nice-线程调度的优先级,cgrp-线程调度组,sched-线程调度策略和优先级,handle-线程处理
上下文信息:state-线程调度状态,schedstat-线程在 CPU 中的执行时间、线程等待时间、线程执行的时间片长度,utm-线程在用户状态中调度的时间值,core-最后执行这个线程的 CPU 核序号
堆栈信息:stack-堆栈地址,stackSize-堆栈大小
余下的为堆栈信息,也是我们分析引发 ANR 问题的关键
由于 ANR 只会发生在主线程,主线程的状态也是需要关注的。