ANR机制

对ANR实现原理的探究和总结

ANR(Application Not Responding)

ANR是由于主线程阻塞引起的,不过主线程阻塞不一定引起ANR,尝试在Activity的onCreate中进行无限循环,界面卡住了,主线程被成功阻塞,不过并没有ANR。这说明ANR是在一定的场景下才能出现的。

ANR出现的场景

Service ANR:Service Timeout是位于”ActivityManager”线程中的AMS.MainHandler收到SERVICE_TIMEOUT_MSG消息时触发。

对于Service有两类:

对于前台服务,则超时为SERVICE_TIMEOUT = 20s;
对于后台服务,则超时为SERVICE_BACKGROUND_TIMEOUT = 200s

BroadcastQueue ANR:BroadcastReceiver Timeout是位于”ActivityManager”线程中的BroadcastQueue.BroadcastHandler收到BROADCAST_TIMEOUT_MSG消息时触发。
对于广播队列有两个: foreground队列和background队列:

对于前台广播,则超时为BROADCAST_FG_TIMEOUT = 10s;
对于后台广播,则超时为BROADCAST_BG_TIMEOUT = 60s

ContentProvider ANR:ContentProvider Timeout是位于”ActivityManager”线程中的AMS.MainHandler收到CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息时触发。ContentProvider 超时为CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10s. 这个跟前面的Service和BroadcastQueue完全不同, 由Provider进程启动过程相关.

InputDispatching ANR:输入事件必须在5秒内处理完毕。在派发一个输入事件时,会判断当前输入事件是否需要等待,如果需要等待,则判断是否等待已经超时,超时就说明发生了ANR.

ANR的报告机制

对于Service, Broadcast, Input发生ANR之后,最终都会调用AMS.appNotResponding;
这个方法的职能就是向用户或开发者报告ANR发生了。 最终的表现形式是:弹出一个对话框,告诉用户当前某个程序无响应;输入一大堆与ANR相关的日志,便于开发者解决问题。

对于provider,在其进程启动时publish过程可能会出现ANR, 则会直接杀进程以及清理相应信息,而不会弹出ANR的对话框. appNotRespondingViaProvider()过程会走appNotResponding(), 这个就不介绍了,很少使用,由用户自定义超时时间.

Service,BroadcastQueue都是在AMS中埋炸弹的,然后客户端执行完生命周期之后,再向AMS中发送消息拆炸弹。如果超时没拆,那就beng,ANR了。原理其实就是Handler发一个延时消息,然后到时间还没remove掉就ANR。

参考链接:

http://gityuan.com/2016/07/02/android-anr/

http://duanqz.github.io/2015-10-12-ANR-Analysis

文章目录
  1. 1. ANR(Application Not Responding)
    1. 1.1. ANR出现的场景
    2. 1.2. ANR的报告机制
|