【Android】应用ANR分析

一、什么是ANR?

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

《【Android】应用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的种类有以下三种:

  1. 主要类型:KeyDispatchTimeout(5 seconds)

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

  1. 小概率类型:BroadcastTimeout(10 seconds)

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

  1. 小概率类型: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 导出后的路径

  人工制造ANR事件传送门

  • traces.txt文件内容分析
    打开traces.txt文件后我们会看到如下图内容:
    《【Android】应用ANR分析》 traces.png
    这里我已经标出了问题产生位置、原因以及应用包名,关于traces.txt内具体信息的查阅,可以参考
    traces.txt Log分析

未完待续
新手上路,欢迎指正批评。

【参考文章】

    原文作者:紫豪
    原文地址: https://www.jianshu.com/p/1f720fef3cf0
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞