Android中的ANR异常如何分析又该怎么去避免ANR

ANR是个什么玩意

       ANR,是“Application Not Responding”的缩写,即“应用程序无响应”。系统会向用户显示一个对话框,用户可以选择“等待”而让程序继续运行,也可以选择“强制关闭”。

       在Android中,应用程序的响应是由Activity Manager和WindowManager系统服务监视的 。当它监测到A、B、C情况中的一个时,Android就会针对特定的应用程序显示ANR:

A.在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸)--主要类型

B.BroadcastReceiver在10秒内没有执行完毕

C.Service在特定时间内(20秒内)无法处理完成--小概率类型

       造成ABC的原因有很多,比如在主线程中做了非常耗时的操作,如下载,io异常等。还需要注意的是产生这种ANR的前提是要有输入事件,如果用户没有触发任何输入事件,即便是主线程阻塞了,也不会产生ANR,因为InputDispatcher没有分发事件给应用程序,当然也不会检测处理超时和报告ANR了。

1.如何分析ANR

       ANR发生时都会在log中输出错误信息,从log中可以获得ANR的类型,CPU的使用情况,CPU使用率过高有可能是CPU饥饿导致了ANR。CPU使用率过低说明主线程被block了,如果IOwait高是因为主线程进行I/O操作造成的。

       除了log输出外,你会发现各个应用进程和系统进程的函数堆栈信息都输出到了一个/data/anr/traces.txt的文件中,这个文件是分析ANR原因的关键文件.要获取到该文件可使用adb指令进行赋权后拉出查看调用stack。通过log、trace.text、代码结合分析ANR的成因(iowait?Memoryleak?Block?)

2.怎么避免ANR

要避免问题的产生,就要抓住问题产生的原因(ABC三种):

(1)避免在主线程上进行复杂耗时的操作,比如说发送接收网络数据/进行大量计算/操作数据库/读写文件等。这个可以通过使用AsyncTask或者使用多线程来实现。

(2)broadCastReceiver 要进行复杂操作的的时候,可以在onReceive()方法中启动一个Service来处理

(3)在设计及代码编写阶段避免出现出现同步/死锁或者错误处理不恰当等情况。


该文章只是简单概括介绍ANR,很多ANR问题trace文件是分析不了的,例如我们的系统上,人脸识别活体攻击的时候,native算法耗尽cpu资源导致其他app无法抢占cpu时间片导致anr,假如ANR的app是你开发的,估计查到死也找不到问题所在,类似这类问题也写过简要的分析文章:

Android ANR分析详解

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 154,645评论 23 678
  • 在实际情况中,当Android项目的用户量特别大时候,一些细小的问题也会被放大,ANR问题就是一个典型的例子。一些...
    qintong000阅读 48,764评论 4 112
  • 一、什么是ANR? ANR(Application Not Responding),中文意指程序未响应——当应用不...
    紫豪阅读 1,492评论 0 9
  • ==================================================== 一:什么...
    爱情小傻蛋阅读 5,105评论 2 28
  • 芒果小姐暗恋甘蔗先生很久很久,终于鼓起了勇气交出粉色的告白信,甘蔗先生感动的拒绝了。 甘蔗先生:“在我眼里你太胖了...
    Lemon酱家的狐小狸阅读 107评论 0 3