Android 面试之ANR

71 阅读2分钟

1. 什么是ANR

ANR(Application Not responding),是指应用程序未响应,Android系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间能未能得到有效响应或者响应时间过长,都会造成ANR。

2. 什么场景产生ANR

  • Service Timeout: 前台服务在20s内未执行完成,后台服务200s内未执行完成。
  • BroadcastQueue Timeout:前台广播在10s内未执行完成,后台广播在60s内未执行完成。
  • ContentProvider Timeout:内容提供者,publish超时10s未完成。
  • InputDispatching Timeout: 输入事件分发超时5s,包括按键和触摸事件。

3. 什么原因导致ANR

应用层导致ANR:

  • 函数阻塞:如死循环、主线程IO、处理大数据。
  • 锁出错:主线程等待子线程的锁。
  • 内存紧张:系统分配给一个应用的内存是有上限的,长期处于内存紧张,会导致频繁内存交换,进而导致应用的一些操作超时。

系统导致ANR:

  • CPU被抢占:一般来说,前台在玩游戏,可能会导致你的后台广播被抢占。
  • 系统服务无法及时响应:比如获取系统联系人等,系统的服务都是Binder机制,服务能力也是有限的,有可能系统服务长时间不响应导致ANR。
  • 其他应用占用大量内存

4. ANR dump主要流程

ANR流程基本是在system_server系统进程完成的,系统进程的行为我们很难监控到,想要监控就得从系统进程与应用进程沟通的边界着手,看边界上有没有可以操作的地方。

不管是怎么发生的ANR,最后都会走到appNotResponding ,比如输入超时的路径。

ActivityManagerService#inputDispatchingTimedOut

AnrHelper#appNotResponding

AnrConsumerThread#run

AnrRecord#appNotResponding

ProcessRecord#appNotResponding

5. 线上监控方案

  • 通过 FileOberver 监控上述的ANR信息文件的变化, 如果这个文件发生了变化,那就说明发生了ANR, 那便可以把它上报到服务器,进行详细的分析【高版本需注意权限问题】。
  • 集成 ANR WatchDog

原理:启动一个异步线程,在while循环中,使用主线程的Handler发送一个消息,线程休眠指定的时间5s,当线程唤醒之后,如果发送的消息还没被主线程执行,即认为主线程发生了卡顿。

  • SIGQUIT信号监控

通过拦截SIGQUIT来判断系统是否向进程发送信号

收到SIGQUIT后,判断主线程是否block,如果主线程block,上报ANR

循环获取App ErrorState,如果状态变成NOT_RESPONDING,上报ANR