ANR产生的原因

只有当应用程序的UI线程响应超时时才会引起ANR,超时产生原因一般有两种:

--当前的事件没有机会得到处理,例如UI线程正在响应另一个事件,当前事件由于某种原因被阻塞了。

--当前的事件正在处理,但是由于耗时太长没能及时完成。

根据ANR产生的原因不同,超时时间也不尽相同,从本质上讲,产生ANR的原因有三种,大致可以对应到Android中的四大组件中的三个:

--KeyDispatchTimeout 最常见的一种类型,原因是View的按键事件或触摸事件在特定的时间(5秒)内无法得到响应。

--BroadcastTimeout的原因是BroadcastReceiver的onReceive()函数运行在主线程中,在特定的时间(10秒)内无法完成处理。

--ServiceTimeout是比较少出现的一种类型,原因是Service的各个生命周期函数在特定时间(20秒)内无法完成处理。

当发生ANR时,在手机内部存储的/data/anr/traces.txt文件会被生成,还有logcat日志也有相应的信息生成。

logcat日志中的关键词是wrote stack traces to '/data/anr/traces.txt',还包含如下内容:

--导致ANR的类名及所在包名

--发生ANR的进程名及ID

--ANR产生的原因Reason

--系统中活跃进程的CPU占用率

同时如果由于ANR导致应用发生崩溃,那么除了打印出上面的信息之外,还调用CrashAnrDetector打印出其他辅助信息。

Traces.txt文件中可以看到如下有助于定位问题的信息:

--发生ANR的进程名称、ID,以及时间

--手机的CPU架构

--主线程基本信息(名称、优先级、锁ID、状态)

--主线程的详细信息

--线程组名称

--线程的Java对象地址

--线程本身的Native对象地址

--线程的调度信息

--线程的上下文信息

--线程的堆栈信息

为了避免ANR,我们也可以借助于一些工具来进行检测:

--StrictMode是Android SDK提供的一个用来检测代码中是否存在违规操作的工具类,StrictMode主要检测两大类问题。其中线程策略ThreadPolicy包括

   1)detectCustomSlowCalls(检测自定义耗时操作)

   2)detectDiskReads(检测是否存在磁盘读取操作)

   3)detectDiskWrites(检测是否存在磁盘写入操作)

   4)detectNetwork(检测是否存在网络操作)

    虚拟机策略V名Policy包括

   1)detectActivityLeaks(检测是否存在Activity泄漏)

   2)detectLeakedClosableObjects(检测是否存在未关闭Closable对象泄漏)

   3)detectLeakedSqlLiteObjects

   4)setClassInstanceLimit(检测类实例个数是否超过限制)

   StrictMode的使用很简单,我们只需要在应用初始化的地方,例如Application或MainActivity的onCreate方法执行StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());其中的penalty表示在Logcat中打印日志,detectAll方法表示启动所有的检测策略。

--BlockCanary是一个非侵入式的性能检测函数库,它的用法和LeakCanary类似,只不过后者监控应用的内存泄漏,而BlockCanary主要用来监控应用主线程的卡顿。它的基本原理是利用主线程的消息队列处理机制,通过对比消息分发开始和结束的时间点来判断是否超过设定的时间。它的集成很简单,首先在build.gradle中添加在线依赖,在Application类中就可以创建BlockCanaryContext及其子类设置各种检测条件,并调用BlockCanary的install方法关联BlockCanaryContext并开始工作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值