ANR
概念
ANR(Application Not responding),是指应用程序未响应,android系统对于一些时间需要在一定的时间范围内完成,如果超过预定时间未能有效响应或者响应时间过长,都会造成ANR
场景
- Service TimeOut
- BroadcastQueue TimeOut
- ContentProvider TimeOut
- InputDispatching TimeOut
TimeOout时长
- 对于前台服务,则超时为SERVICE_TIMEOUT = 20s
- 对于后台服务,则超时为SERVICE_BACKGROUND_TIMEOUT = 200S
- 对于前台广播,则超时为BROADCAST_FG_TIMEOUT = 10S
- 对于后台广播,则超时为BROADCAST_BG_TIMEOUT = 60S
- ContentProvider 超时为CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10S
- InputDispathing TIMEOUT :输入时间分发超时为5S,包括按键和触摸事件
注意事项:Input 的超时机制与其他不同,对于Input来说明即便某次事件执行时间如果超过TimeOut时间,只要用户后续再生成输入事件,则不会触碰ANR
超时检测机制
- Service 超时检测机制
超过一定时间没有执行完响应操作来触发移除延时消息,则会触发ANR
- BroadcastReceive 超时检测机制
有序广播的总执行时间超过2 * receive个数 * timeout 时长,则会触发anr
有序广播的某一个receiver执行过程超过timeOut时长,则会触发anr
- 另外:
① 对于Service,BroadCast,Input发生ANR之后,最终都会调用AMS.AppNotResponding
② 对于provider,在其进程启动时,publish过程可能会出现ANR,则会直接杀进程以及清理相应信息,而不会弹出ANR的对话框
前台与后台的ANR
- 前台ANR:用户能感知,比如拥有前台可见的activity进程,或者拥有前台通知的fg-service的进程,此时发生anr对用户体验影响比较大,需要弹框让用户决定是否退出还是等待
- 后台ANR:只抓取发生无响应进程的trace,也不会收集CPU信息,并且会在后台直接杀掉无响应的进程,不会弹框提示用户
ANR分析
- 前台ANR发生后,系统会马上抓取现场的信息,用于调试分析,收集的信息如下:
- 将am_anr 信息输出到EventLog,也就是说ANR触发的时间点最接近的就是EventLog中输出的am_anr信息
- 收集一下重要进程各个线程调用栈trace信息,保存在data/anr/traces.txtj文件
- 当前发生ANR的进程,system_server进程以及所有persistent进程
- audioserver,cameraserver,meidaserver,sufaceflinger等重要的native进程
- CPU使用率排名前5的进程
- 将发生ANR的reason以及CPU使用情况信息输出到main_log
- 将trace文件和CPU使用情况保存到dropbox,即data/system/dropbox目录
- 对用户可感知的进程则弹出ANR对话框告知用户,对用户不可感知的进程发生ANR则直接杀掉
- 分析步骤
a. 定位发生ANR的时间点
b. 查看trace信息
c. 分析是否有耗时的message,binder调用,锁的竞争,CPU资源的抢占
d. 结合具体业务场景的上下文分析
如何避免ANR
- 主线程尽量只做UI相关的操作,避免耗时操作,比如过度复杂的UI绘制,网络操作,文件IO操作
- 避免主线程跟工作线程发生锁的竞争,减少系统耗时binder的调用,谨慎使用sharePreference,注意主线程执行provider query操作
总之,尽可能减少主线程的负载,让其空闲待命,以期可随时响应用户的操作