一、什么是ANR
ANR是Android系统中的一种错误状态,全称为Application Not Responding,中文翻译为“应用无响应”。当Android系统检测到应用程序在一段时间内未能响应用户输入或无法执行主要的UI线程操作时,就会触发ANR错误。ANR是一种系统保护机制,旨在确保应用的响应性,防止用户在使用应用时遇到卡顿或无响应的情况。
二、ANR的分类
超时时间都是在AMS中定义的
ANR类型 | 解释 | 超时时间 |
---|---|---|
InputDispatching Timeout | 按键或触摸事件在特定时间内无响应 | 5秒 |
Broadcast Timeout | BroadcastReceiver的onReceive方法在特定时间内无法处理完成。 | 前台广播在Android8.0之前10秒8.0之后15秒,后台广播60秒 |
Service Timeout | Service在特定的时间内生命周期函数无法处理完成 | 前台服务20秒后台服务200秒 |
ContentProvider Timeout | ContentProvider在特定的时间内没有完成发布 | 10秒 |
三、产生ANR的原因
主线程阻塞: 当应用在主线程执行耗时操作时,例如网络请求或复杂计算I/O操作,会导致主线程无法及时响应用户输入,触发ANR。
死锁: 多线程编程中,死锁可能发生,当一个线程等待另一个线程释放锁时,应用就会无法继续执行,导致ANR。
非法耗时操作: Android规定在主线程中不允许执行耗时操作,违反这一规定会触发ANR。
**同步Binder调用:**主线程在对另一个进程进行同步Binder调用,而后者需要很长时间才能返回。(如果我们知道调用远程方法需要很长时间,我们应该避免在主线程调用)
关于上述ANR的分析定位参照:Android造成ANR的常见原因及示例分析 - 简书 (jianshu.com)
四、上线后的App如何检测ANR
1.ANR WatchDog
既然 ANR 的原因是输入在定时间内没有响应,那么我们很自然地想到,向主线程发送一个任务,如果一段时间内没有被执行的话,就认为发生了 ANR
这个思路主要有以下几个问题
- 不准确,超时条件不一定会导致 ANR,例如,5 秒超时只是在 TouchEvent 未被消耗时发生 ANR 的条件之一,而其他条件则不一定是 5 秒。
- 漏检测:如果超时时间定为 5 秒,去检测 TouchEvent 的 ANR 存在一定的漏检测的概率(周期不同步。
2.信号监听思路
在上面介绍 ANR 总体流程时,我们注意到当 ANR 发生时会发送 SIGQUIT(通常为信号3)信号,那么我们通过监听这一信号不就可以实现 ANR 监控了吗?事实上 XCrash 与 Matrix 都是通过这种方式实现 ANR 监控的
在这里需要注意,默认情况下进程通过SignalCatcher
监听SIGQUIT
信号,进行堆栈转储生成 ANR Trace 文件。因此当我们监听SIGQUIT
信号后,需要重新向SignalCatcher
发送SIGQUIT
如果缺少重新向 SignalCatcher 发送 SIGQUIT 信号的步骤,Android System 管理服务(AMS)将一直等待 ANR 进程写入堆栈信息。直到超过20秒的超时时间,AMS 才会被迫中断,并继续后续流程。这将导致 ANR 弹窗的显示非常缓慢(因为超时时间为20秒),同时在 /data/anr 目录下也无法生成完整的 ANR Trace 文件。
这个思路主要有下面几个问题
当监听到 SIGQUIT 信号时,不一定是发生了 ANR。
Matrix 的文档中提到了两种误报的情况:
- 比如可能是其它进程 ANR 了,发生 ANR 的进程不是唯一需要进行堆栈转储的进程。系统会收集许多其他进程进行堆栈转储,用于生成 ANR Trace 文件
- 厂商或者是开发者自己发送的
SIGQUIT
信号,发送SIGQUIT信号其实是很容易的一件事情
因此我们需要在监听到信号时再进行一次检查:在 ANR 弹窗前,会给发生 ANR 的进程标记一个 NOT_RESPONDING 的 flag,而这个 flag 我们可以通过 ActivityManager 来获取
漏报情况处理
当进程被标记为 NOT_RESPONDING 时一定发生了 ANR,但是当进程发生了 ANR 时,不一定会被标记为 NOT_RESPONDING
Matrix 的文档中提到了两种漏报情况
- 后台ANR(SilentAnr): 后台 ANR 会直接杀死进程,不会走到标记状态的代码
- 厂商定制逻辑: 相当一部分机型(比如 OPPO、VIVO 两家的高版本 Android )修改了 ANR 的逻辑,即使是前台 ANR 也会直接杀死进程
Matrix 通过判断主线程在收到 SIGQUIT 信号时是否处于卡顿状态来判断当前是否发生 ANR
问题:
2 sp为什么会导致ANR
4项目上线后如何检测ANR(handle watchDog,信号机制)
参考连接:https://juejin.cn/post/7314135212355092491文章来源:https://www.toymoban.com/news/detail-859258.html
https://juejin.cn/post/7229370243146727484文章来源地址https://www.toymoban.com/news/detail-859258.html
到了这里,关于Android ANR产生的原因以及解决方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!