乐闻世界logo
搜索文章和话题

Android中ANR是什么,如何定位和解决ANR问题?

3月6日 23:09

Android ANR详解

ANR(Application Not Responding)是Android系统中当应用程序在特定时间内无法响应用户输入或广播时的错误状态。

ANR的触发条件

类型触发条件时间限制
输入事件ANR按键或触摸事件未响应5秒
BroadcastReceiver ANRonReceive()执行超时前台10秒,后台60秒
Service ANRService生命周期方法执行超时20秒
ContentProvider ANRContentProvider操作超时10秒

ANR产生的原因

1. 主线程耗时操作

  • 网络请求在主线程执行
  • 大量数据库操作
  • 复杂的计算任务
  • 加载大文件或图片

2. 死锁

  • 主线程等待子线程释放锁
  • 子线程又等待主线程释放锁

3. 内存不足

  • 系统资源紧张
  • 频繁GC导致卡顿

4. Binder通信超时

  • 跨进程调用超时
  • 服务端进程无响应

ANR的定位方法

1. 查看Logcat日志

shell
E/ActivityManager: ANR in com.example.app E/ActivityManager: Reason: Input dispatching timed out

2. 分析traces.txt文件

shell
/data/anr/traces.txt

包含:

  • 所有线程的堆栈信息
  • ANR发生的时间点
  • 阻塞的代码位置

3. 使用Android Studio Profiler

  • CPU Profiler查看主线程状态
  • 识别耗时方法

4. StrictMode检测

java
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .build());

ANR的解决方案

1. 异步处理耗时操作

java
// 使用AsyncTask(已废弃,建议使用其他方式) // 使用线程池 ExecutorService executor = Executors.newFixedThreadPool(4); executor.execute(() -> { // 耗时操作 }); // 使用Kotlin协程 lifecycleScope.launch(Dispatchers.IO) { // 耗时操作 }

2. 使用HandlerThread

java
HandlerThread handlerThread = new HandlerThread("background"); handlerThread.start(); Handler backgroundHandler = new Handler(handlerThread.getLooper());

3. 优化数据库操作

  • 使用事务批量操作
  • 建立合适的索引
  • 避免主线程查询大量数据

4. 避免死锁

  • 统一锁的获取顺序
  • 使用tryLock()替代lock()
  • 减少锁的持有时间

面试要点

  • ANR是系统保护机制,不是崩溃
  • traces.txt是定位ANR的关键
  • 主线程不能执行耗时操作
  • 使用Systrace分析性能问题
  • 关注卡顿监控和线上ANR收集
标签:Android