目录
在Android中排查ANR(Application Not Responding)问题是一个系统性工作,下面我来详细讲解ANR的排查方法、ANR文件分析以及跟进策略。
1. ANR文件详解
ANR文件位置
#传统ANR文件位置
/data/anr/traces.txt
#Android 8.0+ 新的ANR文件位置
/data/anr/anr_*
ANR文件内容结构
----- pid 12345 at 2023-10-01 10:00:00 -----
Cmd line: com.example.app
Build: Android 10
"main" prio=5 tid=1 Native
| group="main" sCount=1 dsCount=0 flags=1 obj=0x732c1f10 self=0x7f88c8a400
| sysTid=12345 nice=-10 cgrp=default sched=0/0 handle=0x7fa1a4b4a0
| state=S schedstat=( 123456789 987654321 1234 ) utm=12 stm=34 core=0 HZ=100
| stack=0x7fc35a8000-0x7fc35aa000 stackSize=8192KB
| held mutexes=
at java.lang.Object.wait(Native method)
- waiting on <0x0abcd123> (a java.lang.Object)
at java.lang.Thread.join(Thread.java:786)
- locked <0x0abcd123> (a java.lang.Object)
at com.example.app.MainActivity.doHeavyWork(MainActivity.java:123)
从这个堆栈中可以看出,主线程正在等待一个线程的结束(Thread.join),而该线程可能一直无法结束,导致主线程被阻塞。
根据这个信息,你可检查代码中MainActivity.java的第123行,看看是否在哪里调用了Thread.join()并检查那个线程为什么没有及时结束。
2.ANR排查步骤
步骤1: 获取ANR文件
# 从设备拉取ANR文件
adb pull /data/anr/traces.txt ./
# 或者拉取所有ANR文件
adb shell "ls /data/anr/anr_*" | xargs -I {} adb pull {} ./
步骤2: 分析主线程状态
在ANR文件中查找主线程(通常是“main”线程)的堆栈:
// 常见的ANR原因示例
// 1. 主线程执行耗时操作
public void onButtonClick(View view) {
// 错误:在主线程执行耗时操作
heavyCalculation(); // 这会导致ANR
}
// 2. 主线程等待锁
public void methodA() {
synchronized(lockObject) {
// 持有锁的同时等待其他线程
methodB();
}
}
public void methodB() {
synchronized(lockObject) {
// 死锁情况
}
}
步骤3: 检查CPU使用情况
在ANR文件中查找CPU使用信息:
CPU usage from 0ms to 10000ms later:
50% 1234/com.example.app: 40% user + 10% kernel / faults: 1234 minor
30% 567/system_server: 25% user + 5% kernel
3 常见ANR场景及解决方案
场景1: 主线程网络请求
// 错误示例
public void fetchData() {
// 主线程中执行网络请求
String result = httpClient.execute(request); // 可能导致ANR
updateUI(result);
}
// 正确解决方案
public void fetchData() {
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void...<

最低0.47元/天 解锁文章
1524

被折叠的 条评论
为什么被折叠?



