欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > ANR学习

ANR学习

2025/10/2 18:12:45 来源:https://blog.csdn.net/qq_61923884/article/details/145585629  浏览:    关键词:ANR学习

一、ANR 概述

ANR 是 Android 系统用于监控应用是否及时响应的关键机制。形象地说,如同设置定时炸弹场景:系统的中控系统(system_server 进程)启动倒计时,若应用进程在规定时间内未完成特定任务,中控系统将触发 ANR,采取杀进程等措施;反之,若应用按时完成任务并向中控系统报告,炸弹则被拆除。触发 ANR 后,中控系统会封装现场、抓取快照(traces),以便后续排查问题根源。

二、四类超时机制

Service的ANR超时机制


图片流程解释
1.App进程向中控系统(system_server进程)发送启动服务请求
2.中控系统派发出一个通讯员(线程1)接收这个请求,然后转交给(ActivityManager),并安装定时炸弹
3.通讯员(线程1)通知目标阵营(Service进程)中的通讯员(线程3)让目标阵营开始做事
4.通讯员(线程3)将这个消息转达给做事的人(main),但是要排队(MessageQueue)。
5.经过努力,做事的人终于完成了事情(Service的启动的生命周期),然后开始等待SP持久化。
6.做事的人在做完事情后直接通知中控系统的负责接收的通信员(线程2),说明已经做完事情
7.通讯员(线程2)收到消息后,即刻拆除炸弹。如果此前操作超过时间阈值就来不及了。

SP持久化

它会将内存中的数据写入磁盘文件,并且会阻塞当前线程,直到数据成功写入或者写入失败。


与ANR关系
如果这个写入操作耗时过长,就会导致主线程被阻塞,无法及时处理其他消息和事件。当主线程阻塞时间超过系统设定的阈值(如用户输入事件 5 秒无响应、广播接收器 10 秒未处理完广播等),就会触发 ANR。

相关函数

commit() 方法
这是一个同步操作。调用 commit() 后,系统会将数据写入内存中的映射结构,并且会阻塞当前线程,直到数据成功写入磁盘文件或者写入失败。它会返回一个布尔值,表示写入是否成功。

apply() 方法
这是一个异步操作。调用 apply() 后,系统会将数据写入内存中的映射结构,并立即返回,不会阻塞当前线程。
然后,系统会在后台线程中异步地将数据写入磁盘文件。所以当你调用 apply() 后,不会立即完成持久化,可能需要等待一段时间。
通常推荐在主线程使用apply,因为异步执行不阻塞当前线程,但如果在一些特点场景下就不同了,比如下面的Broadcast的静态注册,它要求SP必须全部持久化到磁盘才能做其他的事情。在这种情况下如果过度使用apply会增大应用ANR的概率

Broadcast的ANR超时机制(静态注册)


图片流程解释
1.App进程向中控系统(system_server进程)发送广播请求
2.中控系统派发出一个通讯员(线程1)接收这个请求,然后转交给(ActivityManager)
3.(ActivityManager)来埋下定时炸弹
4.通讯员(线程1)通知目标阵营(Service进程)中的通讯员(线程3)让目标阵营开始做事
5.通讯员(线程3)将这个消息转达给做事的人(main),但是要排队(MessageQueue)。
6.经过努力,做事的人终于完成了事情(完成receiver启动的生命周期),但是SP正在执行文件操作,于是将汇报任务完成的工作交给了接盘侠(queued-work-looper线程)。
7.接盘侠终于完成了SP持久化的工作后,向中控系统汇报。
8.通讯员(线程2)收到消息后,即刻拆除炸弹。如果此前操作超过时间阈值就来不及了。
注意(如果是动态广播,或者静态广播没有正在执行持久化操作的SP任务,则不需要经过“queued-work-looper”线程中转,而是直接向中控系统汇报)


Provider的ANR超时机制


provider的超时是在provider进程首次启动的时候才会检测


图片流程解释
1.App进程向中控系统(system_server进程)发送内容提供者请求
2.中控系统派发出一个通讯员(线程1)接收这个请求,如果检测到内容提供者(provider),则先通过Zygote孵化进程
3.新孵化的provider进程向中控系统注册自己的存在
4.中控系统派发出一个通讯员(线程2)接收这个请求,然后转交给(ActivityManager),并安装定时炸弹
5.通讯员(线程2)通知目标阵营(Service进程)中的通讯员(线程4)让目标阵营开始做事
6.通讯员(线程3)将这个消息转达给做事的人(main),但是要排队(MessageQueue)。
7.经过努力,做事的人终于完成了事情(完成provider的安装工作)后直接向中控系统汇报事情已完成
8.通讯员(线程3)收到消息后,即刻拆除炸弹。如果此前操作超过时间阈值就来不及了。

Input的ANR超时机制


input变扫雷了


图片流程解释
1.Inputreader通过EventHub监听底层上报的输入事件,一旦收到输入事件就将其放到输入队列中,并唤醒InputDispatcher
2.InputReader会先检查是否有正在处理的事件,如果没有就从输入队列取出事件,并赋值给mPendingEvent,并且重置ANR的定时;否则不会取出事件,也不会重新定时。
然后检查窗口是否就绪,如果就绪条件满足其一就会进入扫雷(检查前一个正在处理的事件是否超时)
按键事件:输出队列和等待队列不为空
非按键:等待队列不为空,且等待队头超时500ms

如果满足就是终止,不满足就安全了进入3
3.将mPendingEvent转移到输出队列
4.当输出队列不为空,并且与应用通信管道连接正常,则从输出队列取出事件放到等待队列
5.inputdispatcher通过socket告知目标应用进程可以开始干活
6.App的做事的人(main)收到事件后,会转发到对应目标窗口
7.做事的人完成工作后,向中控系统汇报完成,中控系统会将事件从等待队列移除。

三、时间阈值

  • Input:用户输入操作时,应用 5 秒内未处理输入事件;输入法弹出或隐藏等操作超过 5 秒未完成。
  • Service:前台 Service 20 秒内未完成启动;后台 Service 200 秒内未完成启动;Service 的 onStartCommand 等方法执行耗时操作超相应时间限制。
  • Broadcast:静态注册的广播接收器 10 秒内未完成广播处理;动态注册的广播接收器执行 onReceive 方法耗时超 10 秒;有序广播中前一接收器处理时间过长阻塞广播传递。
  • Content Provider:query 操作因复杂查询、通信问题等超一定时间未返回结果;插入、更新、删除等操作因死锁、资源竞争等超系统设定时间阈值。10秒

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词