ANR产生原因以及定位分析

什么时候会产生ANR
只有当应用程序的UI线程响应超时才会引起ANR,超时产生原因一般有两种。
1.UI线程正在响应另外一个事件,当前事件由于某种原因被阻塞了。
2.当前的事件正在处理,但是由于耗时太长没能及时完成。

Activity/View 中按键或者触摸事件在5秒内无法得到响应。
BroadcaseReceicer 的onReceive() 函数运行在主线程中,在特定事件10秒内无法处理完成。
Service 的各个声明周期函数载20秒内无法结束。

实际场景举例:
1.UI线程中进行文件IO操作以及数据库操作,导致无法及时处理用户事件。
2.UI线程等待子线程释放所,无法处理用户输入请求。
3.耗时动画占用大量CPU资源导致,CPU负载过重。

ANR问题的定位与分析
1.在发生ANR的场景中寻找耗时操作添加Log,缩小定位范围。
2.根据logcat日志信息来判断 /data / anr/traces.txt
traces.txt 中包含的主要信息如下
(1)导致ANR的类名以及所在包名。
(2)发生ANR的进程名称以及ID。
(3)ANR的类型。
(4)系统中活跃进程的CPU占用率。

ANR的避免和监测
StrictMode
严格模式StrictMode 是 Android SDK 提供的一个用来检测代码中是否存在违规操作的工具类。StrictMode主要检测两大类问题。
线程策略ThreadPolicy
detectCustomSlowCalls: 检测自定义耗时操作。
detectDiskReads: 检测是否存在磁盘读取操作。
detectDiskWrites: 检测是否存在磁盘写入操作。
detectNetwork: 检测是否存在网络操作。

虚拟机策略VmPolicy
detectActivityLeaks: 检测是否存在Activity泄漏。
detectLeakedClosableObjects: 检测是否存在未关闭的Closable对象泄漏。
detectLeakedSqlLiteObjects:检测是否存在Sqlite对象泄漏。
setClassInstanceLimit: 检测类实例的个数是否超过限制。

BlockCanary
基本原理就是用主线程的消息队列处理机制,通过对比消息分发开始和结束的时间点来判断是否超过设定时间,如果是则判断为主线程卡顿。

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