Android 性能优化之 ANR 优化

Android 性能优化之 ANR 优化

  • ANR 是 Application Not Responding 的缩写,即应用程序无响应,当 Android 应用的 UI 主线程无法响应用户操作超过一定的时间(处于阻塞状态的时间过长,可能进行耗时的网络请求、文件读写或复杂计算等),如果此时应用位于前台,系统会弹出"应用程序无响应"对话框,用于提示用户,允许用户选择"等待"或"强制关闭",相当于当系统检测到应用应用的 UI 主线程在一定时间内无法及时响应处理用户输入事件或绘制操作,就会触发 ANR

会触发 ANR 的场景

  • Activity:在 5 秒内未完成 onResume 或者在 5 秒内未响应输入事件(如按键或屏幕触摸)
  • BroadcastReceiver: 前台广播的 onReceive 方法耗时超过大概 10 秒,后台广播超过大概 60 秒
  • Service:前台服务的 onCreate、onStartCommand、onBind 等方法 20 秒内没有执行完成,后台服务则在 200 秒内
  • ContentProvider:query、insert、publish 等方法在 10 秒内没有执行完成
  • JobScheduler 超时:JobService 未在指定时间内(几秒内)完成操作(比如未调用 JobService#setNotification)
  • 主线程处理耗时操作(比如文件 IO 操作或数据库操作等)
  • 布局过于复杂(嵌套层级深、过度绘制)、频繁执行重绘刷新
  • 主线程与子线程发生死锁,或长时间等待同步锁(未正确使用同步机制)
  • 系统内存不足(内存泄漏等导致)、CPU 负载过高导致系统服务响应延迟、频繁 GC 导致主线程被抢占

BROADCAST_TIMEOUT_MSG 广播超时

  • 发送广播时根据广播发送中的 intent 是否带有 FLAG_RECEIVER_FOREGROUND 标记可以分为前台广播和后台广播
java 复制代码
前台广播超时时间
- Android 13 及以下版本 10 秒
- Android 14 及以上版本,10-20 秒,具体取决于进程是否已耗尽 CPU
后台广播超时时间
- Android 13 及以下版本 60 秒
- Android 14 及以上版本,60-120 秒,具体取决于进程是否已耗尽 CPU

优化策略

  • 主线程只做轻量级的操作,使用子线程处理耗时任务
  • 减少布局复杂度,避免复杂的 UI 渲染,减少 UI 刷新频率
  • 使用异步机制或优化同步逻辑,避免死锁和等待同步锁(尝试尽量减少在主线程和子线程之间发生的锁竞争)
  • 根据设备性能加载不同资源(区分设备性能,动态调整资源加载策略),及时避免内存泄漏(包括及时释放大内存对象),通过线程避免频繁创建和销毁线程

排查检测

  • Google Play 收集到的用户感知 ANR 率
  • 当 ANR 发生时,系统会在 Logcat 中生成日志,包含关键信息(如阻塞的线程、调用栈),搜索关键字来定位 ANR 问题
  • 导出 /data/anr/traces.txt(低版本)排查或使用 adb bugreport 获取 bug 报告(内部包含 ANR 日志),通过分析主线程堆栈来定位原因
  • 在开发阶段启用 StrictMode 严格模式,检测主线程中的违规操作(比如磁盘操作或网络访问),以触发警告
  • 通过启用后台 ANR 对话框,在设备的开发者选项中启用了显示所有 ANR 时,比如针对长时间处理广播消息也会显示 ANR 对话框
  • 实现 ANR-WatchDog 检测 ANR,通过自定义线程周期性检查主线程状态(利用子线程轮询主线程消息队列),若长时间未响应则触发日志记录
  • 通过腾讯 Matrix 集成 ANR 监控模块,支持后台 ANR 捕获
  • 利用 Systrace 系统跟踪工具监控系统性能,识别主线程阻塞的原因
  • 利用 Android Studio Profiler 分析应用性能,排查问题原因
相关推荐
2501_916008894 小时前
Web 前端开发常用工具推荐与团队实践分享
android·前端·ios·小程序·uni-app·iphone·webview
我科绝伦(Huanhuan Zhou)5 小时前
MySQL一键升级脚本(5.7-8.0)
android·mysql·adb
怪兽20146 小时前
Android View, SurfaceView, GLSurfaceView 的区别
android·面试
龚礼鹏7 小时前
android 图像显示框架二——流程分析
android
消失的旧时光-19437 小时前
kmp需要技能
android·设计模式·kotlin
帅得不敢出门8 小时前
Linux服务器编译android报no space left on device导致失败的定位解决
android·linux·服务器
雨白8 小时前
协程间的通信管道 —— Kotlin Channel 详解
android·kotlin
TimeFine10 小时前
kotlin协程 容易被忽视的CompletableDeferred
android
czhc114007566311 小时前
Linux1023 mysql 修改密码等
android·mysql·adb
GOATLong12 小时前
MySQL内置函数
android·数据库·c++·vscode·mysql