Android中ANR是什么,【Android】应用ANR分析

一、什么是ANR?

ANR(Application Not Responding),中文意指程序未响应——当应用不能够灵敏地响应用户的操作时(应用响应不及时),ANR就会出现,这时系统会向用户弹出一个提示框,让用户选择继续等待或确定关闭应用,示例如下图:

anr_tips.png

一个合理的应用程序中不应该出现ANR,ANR频繁出现会导致用户体验变差、用户留存率低等问题。

二、为什么会出现ANR?

在Andorid上,系统会通过Activity Manager和Window Manager服务来监控应用的响应情况,如果应用响应超出限定时间了,为了避免对用户的体验造成困扰,系统就会弹出ANR提示供用户选择是否继续等待应用响应。

什么情况下会导致应用响应不及时(出现ANR)?

主线程阻塞

在主线程中做了大量的耗时操作,如网络请求;频繁/大批量的数据操作等。

CPU满负荷工作时进行I/O操作

当CPU使用率达到100%,在应用内仍在主线程上进行频繁的读写操作时,就会导致ANR的产生。

内存不够用

系统分配给每个App的可用内存是有限的,如果App内存在内存泄漏等情况的话,这个是会导致ANR的出现的。

三、ANR的种类

ANR的种类有以下三种:

主要类型:KeyDispatchTimeout(5 seconds)

按键或触摸事件在特定时间(5秒)内无响应。

小概率类型:BroadcastTimeout(10 seconds)

BroadcastReceiver.onReceive()在特定时间(10秒)内无法处理完成。

小概率类型:ServiceTimeout(20 seconds)

Service各个生命周期函数在特定的时间(20秒)内无法处理完成。

四、什么情况下会产生ANR?

出现ANR的前提条件

在Android应用中,ANR并不是随意出现的,它的出现也是有前提条件限制的,大致为以下几条:

只有主线程(UI线程)才会产生ANR;

只有某些特定的操作或者触摸事件才会导致ANR的出现(如:按键或触摸事件、Service或BroadcastReceiver内做耗时操作等);

在上述条件情况下,系统会监测对应的操作是否及时,不同的情况下限制事件也是不一致的:

主线程(UI线程)对触摸、输入事件在5秒内没有处理完毕(如:键盘输入、触摸屏幕等);

主线程在执行BroadcastReceiver的onReceive()函数时10秒内没有处理完毕;

主线程在Service的各个生命周期函数在20秒内没有处理完毕。

除此之外,只有在CPU满负荷工作时做耗时I/O操作、内存不够用的情况下才会产生ANR。

出现ANR情况

在主线程中进行耗时的网络请求、大批量的数据读写、数据库操作;

Service各个生命周期方法内进行和耗时操作,在20s内未处理完毕;

BroadcastReceiver内进行了耗时操作,超过了10s的限制时间;

其它线程持有锁,导致主线程不能够响应;

调用Thread的join()方法、sleep()方法、wait()方法或者等待线程锁的时候;

CPU满负荷时仍进行大量的I/O操作;

应用内内存泄漏导致的响应不及时。

五、如何预防ANR的产生?

其实说来说去,导致ANR发生的罪魁祸首就是在主线程中进行了耗时操作,那么在常规情况下,我们可以通过以下几种方式来防止ANR的产生:

主线程(UI线程)做耗时操作引发ANR预防

不在主线程(UI)线程中做耗时操作,开辟单独的子线程来处理耗时阻塞事务.;

不在Service、BroadcastReceiver内做耗时操作;

不乱用Thread的join()、sleep()、wait()方法。

CPU满负荷工作时进行I/O操作情况下预防

这种情况一般还是I/O操作在主线程上进行导致的,同理可以通过开启子线程的方式解决。

内存不足产生的ANR

排查内存泄漏解决内存不够用的情况,推荐使用LeakCanary。

六、查看、分析ANR信息

获取ANR产生的traces.txt文件

当发生ANR后,系统会在data/anr/目录下生成一个名为traces.txt的文件,文件内主要记录了ANR产生时系统信息的一些情况,我们可以通过adb命令的方式来将文件导出至本地:

adb pull data/anr/traces.txt 导出后的路径

traces.txt文件内容分析

打开traces.txt文件后我们会看到如下图内容:

traces.png

这里我已经标出了问题产生位置、原因以及应用包名,关于traces.txt内具体信息的查阅,可以参考

未完待续

新手上路,欢迎指正批评。

【参考文章】

你可能感兴趣的:(Android中ANR是什么)