什么是 ANR 如何避免它

一、什么是 ANR?

ANR(Application Not Responding) 是 Android 系统在应用程序主线程(UI

线程)被阻塞超过一定时间后触发的错误机制。此时系统会弹出一个对话框提示用户"应用无响应",用户可以选择等待或强制关闭应用。

ANR 的触发条件:

  1. 主线程阻塞超过阈值
    1)输入事件(如点击、滑动) :5 秒内未处理完成。
    2)BroadcastReceiver :前台广播 10 秒内未完成,后台广播 60 秒内未完成。
    3)Service 启动或绑定:前台 Service 5 秒内未完成onCreate()或onStartCommand()。
  2. 主线程执行耗时操作:例如网络请求、数据库查询、文件读写等。

二、ANR 的根本原因

  • 主线程被阻塞:主线程负责 UI 渲染和事件响应,若执行耗时操作,会直接导致界面卡顿或无响应。
  • 过度复杂的布局或绘制:布局嵌套过深、频繁重绘等。
  • 死锁或过度同步:线程间竞争锁资源,导致主线程等待。

三、如何避免 ANR?

1、主线程只处理 UI 和轻量操作

1)禁止在主线程执行以下操作

a)网络请求(HTTP/HTTPS)。

b) 数据库查询(SQLite)。

c) 大文件读写。

d) 复杂计算(如循环、加密解密)。

2)正确做法:使用子线程(如 Thread、HandlerThread)或异步框架(如 Kotlin 协程、RxJava、AsyncTask)。

2、使用异步框架处理耗时任务

1)Kotlin 协程:

2)Rxjava

3、 优化主线程任务

1)减少布局复杂度 :a) 使用 ConstraintLayout 减少嵌套层级;b) 避免 RelativeLayout 或 LinearLayout 的过度嵌套;c) 使用 ViewStub 延迟加载复杂布局。

2)避免过度绘制 :使用 Android Studio 的 Layout Inspector 和 GPU 渲染分析工具 检测绘制性能

3)分批处理数据:若需渲染大量数据(如列表),使用分页加载(Paging Library)或增量更新

4、 避免死锁和过度同步

1)减少锁竞争 :避免在主线程中等待子线程释放锁。

2)使用线程安全的数据结构 :如 ConcurrentHashMap、CopyOnWriteArrayList

3)谨慎使用 synchronized:尽量缩小同步代码块的范围

5、 监控 ANR 并分析日志

1)ANR 日志

a) 系统会在 /data/anr/ 目录下生成 traces.txt 文件,记录 ANR 时的线程堆栈

b) Android 11 及以上版本可通过 adb bugreport 获取更详细的日志

2)第三方监控工具

a) 使用 Firebase Crashlytics、Bugsnag 等工具捕获 ANR 事件。

b) 使用 ANR-WatchDog 库主动检测 ANR。

通过合理设计线程模型、使用现代异步框架,并结合性能分析工具,可显著降低 ANR 的发生概率。

相关推荐
月小水长1 个月前
Django 使用 matplotlib 遇到 RuntimeError: main thread is not in main loop 解决办法
python·django·matplotlib·thread·anr
linweidong2 个月前
Android ANR 监控方法与事件分发耗时优化实战
事件分发·android面试·自定义view·asynctask·anr·android面经·android性能
linweidong5 个月前
唯品会Android面试题及参考答案
android·java多线程·内存泄漏·anr·aidl·安卓面试·安卓面经
画个太阳作晴天5 个月前
Android10 设备死机的问题分析和解决
android·framework·anr
yueqc16 个月前
性能优化(二):ANR
性能优化·anr
Gerry_Liang6 个月前
简单易用的Android主线程耗时检测类 MainThreadMonitor
android·anr·卡顿检测·主线程
码龙12341 年前
Android ANR简介
android·稳定性·anr
月小水长1 年前
Android ANR 日志导出及分析
adb·android-studio·anr
QQ16573792581 年前
Android 应用程序无响应定位ANR原因
android·应用程序无响应·anr·定位anr