Android-ANR小记

113 阅读2分钟

ANR 概念

ANR 机制实际上就是对应用程序主线程性能的限制,要求主线程在限定的时间内处理完一些常见操作(处理输入、启动服务、处理广播), 如果超时,则认为主线程已经失去了响应其他操作的能力。主线程中的耗时操作,如大量 IO、复杂界面布局等,都会降低app的响应能力。

(1)KeyDispatchTimeout input事件在5S内没有处理完成发生了ANR。 logcat日志关键字:Input event dispatching timed out

(2)BroadcastTimeout 前台Broadcast:onReceiver在10S内没有处理完成发生ANR。 后台Broadcast:onReceiver在60s内没有处理完成发生ANR。 日志关键字:Timeout of broadcast BroadcastRecord

(3)ServiceTimeout 前台Service生命周期某个回调在20s内没有处理完成发生ANR。 后台Service生命周期在200s内没有处理完成发生ANR。日志关键字:Timeout executing service

(4)ContentProviderTimeout ContentProvider 在10S内没有处理完成发生ANR。 日志关键字:timeout publishing content providers

ANR 监控

监控原理和卡顿监控类似。定义一个ANR子线程,通过handler给主线程发送一个消息,在发送消息时,在ANR线程中保存一个状态,主线程消息执行完再reset状态,如果ANR线程中超过一定时间没有复位,就认为发生了ANR。

抖音方案:采取类似 Matrix 方案,通过 ASM 字节码工具,在编译时对应用内的业务代码进行插桩,也就是在函数的入口和出口插入一行统计代码,来记录当前方法的运行耗时

ANR 产生的原因

  • 主线程阻塞或主线程数据读取

解决办法:避免死锁的出现,使用子线程来处理耗时操作或阻塞任务。尽量避免在主线程读写数据库,滥用sp等。

  • CPU满负荷,I/O阻塞

解决办法:文件读写或数据库操作放在子线程异步操作。

  • 内存不足

解决办法:AndroidManifest.xml文件中设置 android:largeHeap="true",增大App使用内存。当然最好还是从根本上优化内存。

ANR 面试题

  1. 为什么主线程阻塞了,还能弹出ANR弹窗? :因为ANR不是APP主线程弹的,是系统弹的。
  2. 做过哪些ANR优化? :根据项目讲述,尤其说明结合工具如Systrace来分析。
  3. ANR监控如何实现?:见上
  4. 为什么会产生ANR?:见上