一 ANR简介
ANR和crash的区别:ANR不一定是由于程序的异常错误导致的,一般是应用处理长时间没有响应导致主线程不能处理下一件事情
ANR(Application not responding)即应用无响应,应用发生anr的几种类型
1 KeyDispatchTimeout:最常见的anr类型是对输入事件5s内无响应,比如按键或触摸事件在此时间内无响应
2 BroadcastTime:BroadcastReceiver在指定事件(原生系统默认是10s)内无法处理完成,并且没有结束执行onReceive
3 ServiceTimeout:这种类型在Android应用中出现的概率很小,是指service在特定时间(原生系统是20s)内无法处理完成
引起anr的根本原因总体来说有以下两种:
1)应用程序自身逻辑有缺陷,或者在某些异常场景触发了此缺陷,如主线程堵塞、死循环等导致
2)由于Android设备其他进程的CPU占用高,导致当前应用进程无法抢占到CPU时间片
二 ANR分析
在Android系统上,如果发生ANR,Logcat会产生对于的日志和一个trace文件,主要是分析这两个信息
1)Logcat分析
关键信息如下:
ANR IN:发生anr的具体类
PID:发生ANR的进程,系统在此时会生成trace文件,当前的时间点也是发生anr的具体时间,以及生成trace文件的时间
Reson:当前anr的类型以及导致anr的原因
CPU usage:CPU的使用情况,在日志CPU usage有两个时间点,第一个是发生anr前的CPU使用情况,第二个是发生anr后的CPU使用情况
从logcat中除了能看出在哪个类发生anr以及anr的类型,具体的原因主要还是要看CPU的使用情况,如果CPU使用量很少,说明主线程可能阻塞,如果IOwait很高,说明anr有可能是由于主线程进行耗时的I/O操作造成的
2)trace分析
trace文件保存在/data/anr/trace.txt
这个日志很容易定位是onClick事件中超时导致
Android studio分析trace的工具:Analyze Stacktrace
Analyze Stacktrace使用方法
1 在Android studio工具栏中,选择Analyze ->Analyze Stacktrace,打开Analyze Stacktrace工具窗口
2 将trace.txt中的内容复制到窗口,单击Normalize按钮,生成Thread Dump列表
3 如果某个线程被标红,说明此线程被堵塞了,然后在右边的详细信息中查看堵塞的具体原因
注:部分anr是由于多个线程之前的同步锁导致,在使用Analyze Stacktrace分析时,可以再详情页面查看是在等待哪个线程,再定位到对应的线程