ANR总结

一、什么时候会有Log文件的产生 ?
Log的产生大家都知道 , 大家也都知道通过DDMS来看log , 但什么时候会产生log文件呢 ?一般在如下几种情况会产生log文件 。
1,程序异常退出 , uncaused exception
2,程序强制关闭 ,Force Closed (简称FC)
3,程序无响应 , Application No Response (简称ANR) , 顺便,一般主线程超过5秒么有处理就会ANR
4,手动生成 。
https://blog.csdn.net/itachi85/article/details/6460242

二、ANR触发场景

1、InputDispatching Timeout :输入事件分发超时5s未响应完毕;

2、BroadcastQueue Timeout :前台广播在10s内、后台广播在20秒内未执行完成;

3、Service Timeout :前台服务在20s内、后台服务在200秒内未执行完成;

4、ContentProvider Timeout :内容提供者,在publish过超时10s;
在这里插入图片描述

二、彻底理解安卓应用无响应机制
对于知识学习的过程,要知其然知其所以然,才能做到庖丁解牛般游刃有余。要深入理解ANR,就需要从根上去找寻答案,那就是ANR是如何触发的?

ANR是一套监控Android应用响应是否及时的机制,可以把发生ANR比作是引爆炸弹,那么整个流程包含三部分组成:

埋定时炸弹:
中控系统(system_server进程)启动倒计时,在规定时间内如果目标(应用进程)没有干完所有的活,则中控系统会定向炸毁(杀进程)目标。
拆炸弹
‘在规定的时间内干完工地的所有活,并及时向中控系统报告完成,请求解除定时炸弹,则幸免于难。
引爆炸弹:
中控系统立即封装现场,抓取快照,搜集目标执行慢的罪证(traces),便于后续的案件侦破(调试分析),最后是炸毁目标。
常见的ANR有service、broadcast、provider以及input,更多细节详见理解Android ANR的触发原理,http://gityuan.com/2016/07/02/android-anr

1、service超时机制
在这里插入图片描述
2、broadcast超时机制
在这里插入图片描述
3、provider超时机制
在这里插入图片描述
4、input超时机制
在这里插入图片描述

为什么会超时呢?
超时时间的计数一般是从按键分发给app开始。超时的原因一般有两种:
(1)当前的事件没有机会得到处理(即UI线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)
(2)当前的事件正在处理,但没有及时完成

扫描二维码关注公众号,回复: 10088337 查看本文章

如何避免KeyDispatchTimeout
1:UI线程尽量只做跟UI相关的工作
2:耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理
3:尽量用Handler来处理UIthread和别的thread之间的交互

https://blog.csdn.net/itachi85/article/details/6918761

三、场景

1、耗时操作
请放在工作现场中进行,可以使用Handler、AsyncTask等。
(1)主线程操作调用join()方法、sleep()方法或者wait()方法;
(2)耗时动画/耗资源行为导致CPU负载过重

2、IO 操作
(比如:网络操作、存储操作等)也是引起ANR的常见因素。强烈建议在工作线程中进行。

3、程序锁竞争

某些情况,ANR产生的原因不是直接因为在主线程中产生的。 比如: 工作线程对某个资源等上锁,恰好此时,主线程需要此资源,如等待超时,则此时ANR可能发生。

4、死锁

当主线程因为请求一个其他线程正在持有的资源而进入等待状态时,ANR可能会发生。

5、广播接收慢

应用程序可以通过广播接收器响应广播消息,例如启用或禁用飞行模式或更改连接状态。 当应用程序花费太长时间来处理广播消息时,理论上超过10s 未处理完成,ANR可能会发生。
广播 ANR发生在下列情况下:

(1)onReceive() 方法长时间未执行完毕。

尽量避免在onReceive() 中进行耗时操作。

(2)广播接收者调用goAsync()方法并且未能在PendingResult对象上调用finish()。

如要处理的广播内容较多,请使用IntentService 进行处理。
比如下面例子:

不建议在onReceive 方法中进行耗时操作,超过10s 未处理,会引起ANR
在这里插入图片描述

建议使用IntentService ,避免ANR发生
在这里插入图片描述

您的广播接收机可以使用goAsync()来通知系统需要更多的时间来处理消息。 但是,您应该在PendingResult对象上调用finish()。 以下示例显示如何调用finish()以让系统回收广播接收器并避免ANR:
在这里插入图片描述

6、system server中发生WatchDog ANR;
7、service binder的数量达到上限

https://juejin.im/post/5d527593e51d4561da62011f

发布了18 篇原创文章 · 获赞 2 · 访问量 3165

猜你喜欢

转载自blog.csdn.net/shiningdreamercaihua/article/details/103562397
ANR
今日推荐