android ANR 问题

本文详细探讨了Android应用中的ANR(应用无响应)问题,包括ANR的三种主要类型,导致ANR的常见操作,如何避免和解决ANR的方法,以及排查ANR的具体步骤。文章还介绍了如何使用AsyncTask和Handler来处理耗时操作,以防止UI线程阻塞。

android ANR 问题

前言

1 搞清楚什么是anr
2 搞清楚造成anr的情况
3 如何避免anr以及如何处理anr问题
4 如何分析anr
1、ANR排错一般有三种类型

  1. KeyDispatchTimeout(5 seconds) --主要是类型按键或触摸事件在特定时间内无响应
  2. BroadcastTimeout(10 seconds) --BroadcastReceiver在特定时间内无法处理完成
  3. ServiceTimeout(20 secends) --小概率事件 Service在特定的时间内无法处理完成

2、哪些操作会导致ANR
在主线程执行以下操作:

  1. 高耗时的操作,如图像变换
  2. 磁盘读写,数据库读写操作
  3. 大量的创建新对象

3、如何避免

  1. UI线程尽量只做跟UI相关的工作
  2. 耗时的操作(比如数据库操作,I/O,连接网络或者别的有可能阻塞UI线程的操作)把它放在单独的线程处理
  3. 尽量用Handler来处理UIThread和别的Thread之间的交互

4、解决的逻辑

  1. 使用AsyncTask
    1. 在doInBackground()方法中执行耗时操作
    2. 在onPostExecuted()更新UI
  2. 使用Handler实现异步任务
    1. 在子线程中处理耗时操作
    2. 处理完成之后,通过handler.sendMessage()传递处理结果
    3. 在handler的handleMessage()方法中更新UI
    4. 或者使用handler.post()方法将消息放到Looper中

5、如何排查

  1. 首先分析log
  2. 从trace.txt文件查看调用stack,adb pull data/anr/traces.txt ./mytraces.txt
  3. 看代码
  4. 仔细查看ANR的成因(iowait?block?memoryleak?)

6、监测ANR的Watchdog

#FC(Force Close)
##什么时候会出现

  1. Error
  2. OOM,内存溢出
  3. StackOverFlowError
  4. Runtime,比如说空指针异常

##解决的办法

  1. 注意内存的使用和管理
  2. 使用Thread.UncaughtExceptionHandler接口

参考

https://github.com/francistao/LearningNotes

1、ANR排错一般有三种类型

  1. KeyDispatchTimeout(5 seconds) --主要是类型按键或触摸事件在特定时间内无响应
  2. BroadcastTimeout(10 seconds) --BroadcastReceiver在特定时间内无法处理完成
  3. ServiceTimeout(20 secends) --小概率事件 Service在特定的时间内无法处理完成

2、哪些操作会导致ANR
在主线程执行以下操作:

  1. 高耗时的操作,如图像变换
  2. 磁盘读写,数据库读写操作
  3. 大量的创建新对象

3、如何避免

  1. UI线程尽量只做跟UI相关的工作
  2. 耗时的操作(比如数据库操作,I/O,连接网络或者别的有可能阻塞UI线程的操作)把它放在单独的线程处理
  3. 尽量用Handler来处理UIThread和别的Thread之间的交互

4、解决的逻辑

  1. 使用AsyncTask
    1. 在doInBackground()方法中执行耗时操作
    2. 在onPostExecuted()更新UI
  2. 使用Handler实现异步任务
    1. 在子线程中处理耗时操作
    2. 处理完成之后,通过handler.sendMessage()传递处理结果
    3. 在handler的handleMessage()方法中更新UI
    4. 或者使用handler.post()方法将消息放到Looper中

5、如何排查

  1. 首先分析log
  2. 从trace.txt文件查看调用stack,adb pull data/anr/traces.txt ./mytraces.txt
  3. 看代码
  4. 仔细查看ANR的成因(iowait?block?memoryleak?)

6、监测ANR的Watchdog

#FC(Force Close)
##什么时候会出现

  1. Error
  2. OOM,内存溢出
  3. StackOverFlowError
  4. Runtime,比如说空指针异常

##解决的办法

  1. 注意内存的使用和管理
  2. 使用Thread.UncaughtExceptionHandler接口

参考

https://github.com/francistao/LearningNotes

### Android ANR 问题排查方法 ANR(Application Not Responding)是 Android 应用中常见的性能问题,通常发生在主线程执行耗时操作或资源竞争激烈时。排查 ANR 问题需要结合系统日志、trace 文件、event log 等多个维度进行分析。以下是几种常用的排查方法: 1. **查看 ANR Trace 文件** ANR 发生时,系统会生成一个 trace 文件,通常位于 `/data/anr/` 目录下。该文件记录了 ANR 发生时各线程的状态和调用堆栈,有助于定位主线程卡顿的具体位置。通过分析 trace 文件,可以识别出主线程是否被阻塞、是否发生死锁或长时间等待资源等问题 [^2]。 2. **分析 Event Log 和 Main Log** 使用 `logcat` 或 `bugreport` 提取 event log 和 main log,重点关注 `am_`(ActivityManager)、`wm_`(WindowManager)、`input_focus` 等关键事件。例如,如果发现某个应用生命周期回调(如 `onCreate` 或 `onResume`)耗时过长,可能是由于主线程执行了耗时操作或等待子线程释放锁 [^2]。 3. **识别频繁的 Binder 调用** 在 event log 中查找频繁的 Binder 调用,特别是那些涉及 `system_server` 的加锁接口(如 `binderDied`)。如果某个应用在短时间内发起大量 Binder 请求,可能导致 Binder 队列拥堵,进而引发 ANR [^2]。 4. **关注 Choreographer 和绘制性能** 通过分析 `Choreographer` 相关的日志,可以判断是否发生跳帧现象。如果主线程在执行 UI 绘制时耗时过长,可能会导致界面卡顿并触发 ANR。结合 `OpenGLRenderer` 日志,检查绘制时间是否异常 [^2]。 5. **监控 GC 活动** 频繁的垃圾回收(GC)也可能导致主线程卡顿。在 trace 文件或 log 中查找 `GC freed` 相关信息,判断是否存在内存泄漏或频繁分配对象的问题 [^2]。 6. **模拟 ANR 场景进行测试** 在开发和测试阶段,可以通过人为制造主线程阻塞的场景来模拟 ANR。例如,在 `onCreate` 或 `onResume` 中添加 `Thread.sleep()`,或者在主线程中执行网络请求或数据库查询。此外,也可以通过多线程竞争锁的方式模拟主线程等待资源的场景 [^1]。 7. **使用性能监控工具** Android 提供了多种性能监控工具,如 `Systrace` 和 `Perfetto`,它们可以帮助开发者可视化主线程的执行情况,识别卡顿点和资源竞争问题。通过这些工具可以更直观地分析 ANR 的成因 。 ### 示例代码:模拟主线程阻塞 以下是一个模拟主线程阻塞的代码示例,可用于测试 ANR 的触发条件: ```java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 模拟主线程阻塞 try { Thread.sleep(10000); // 阻塞主线程10秒 } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 在实际开发中,应避免在主线程中执行耗时操作,建议将耗时任务移至子线程,并通过 `Handler` 或 `LiveData` 等机制更新 UI。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值