什么是ANR
ANR即Application Not Responding的缩写,就是应用无响应
首先ANR的发生是有条件限制的,分为以下三点:
1.只有主线程才会产生ANR,主线程就是UI线程;
2.必须发生某些输入事件或特定操作,比如按键或触屏等输入事件,在BroadcastReceiver或Service的各个生命周期调用函数;
3.上述事件响应超时,不同的context规定的上限时间不同
a.主线程对输入事件5秒内没有处理完毕,即阻塞
b.主线程在执行BroadcastReceiver的onReceive()函数时10秒内没有处理完毕
c.主线程在Service的各个生命周期函数时20秒内没有处理完毕
发生ANR后拉取traces.txt分析问题
当系统中有app出现ANR时,当系统中有应用出现ANR时,framework会在弹出Dialog的同时dump出当前各线程的堆栈情况,生成traces.txt文件,方便开发者分析出ANR的root cause。traces文件位于安卓系统下/data/anr目录中;
在这里我们从一份简单的ANR示例来研究当发生ANR后,如何拉取traces.txt文件并分析出ANR原因;
以下为代码示例,很明显的错误,这里假如我们并不知情
下面开始一步一步描述分析问题的步骤
1.导出traces.txt文件
traces.txt位于/data/anr中,无需root权限即可通过pull命令获取,下面的命令可以将traces.txt文件拷贝到当前目录下
因手机厂商可能会自行修改trace文件的命名方式和管理方式,traces文件名和所在目录可能会存在差异,但肯定会再/data/anr/目录下,所以我们可以通过adb shell 进入到 “/data/anr/” 目录下查看traces文件,上图为我再小米手机上导出traces文件的截图,可以看出小米手机是根据anr发生的时间来命名的。
adb shell 进入shell命令模式
cd /data/anr/ 进入anr目录下
ls -a 查看当前目录下的所有文件
adb pull data/anr/anr_2020-09-05-16-03-04-828 导出trace文件到adb命令目录下。
如果拉取遇到权限问题,可以使用“adb bugreport”命令。 会在adb命令所处的目录下生成一个 zip 文件。 解压缩后,在“FS/data/anr” 目录下能看到 anr 文件,不过可能没有后缀,直接用文本软件打开即可。
2.分析traces.txt文件
先看一下traces文件内容,内容较多,无需恐慌,我们只找我们想要的即可
//说明了发生ANR的进程id、时间和进程名称。
----- pid 3551 at 2020-09-05 16:03:04 -----
//发生anr的app包名
Cmd line: com.tiano.anrdemo
Build fingerprint: 'Xiaomi/crux/crux:10/QKQ1.190825.002/V12.0.3.0.QFXCNXM:user/release-keys'
ABI: 'arm64'
Build type: optimized
Zygote loaded classes=8200 post zygote classes=337
Dumping registered class loaders
#0 dalvik.system.PathClassLoader: [], parent #1
#1 java.lang.BootClassLoader: [], no parent
#2 dalvik.system.PathClassLoader: [/system/framework/tcmclient.jar], parent #0
#3 dalvik.system.PathClassLoader: [], parent #0
#4 dalvik.system.PathClassLoader: [/data/app/com.tiano.anrdemo-VyqkZUePQCFk45qOWaBtzw==/base.apk:/data/app/com.tiano.anrdemo-VyqkZUePQCFk45qOWaBtzw==/base.apk!classes2.dex], parent #1
#5 dalvik.system.PathClassLoader: [/system/app/MiuiContentCatcher/MiuiContentCatcher.apk], parent #1
#6 dalvik.system.PathClassLoader: [/system/app/CatcherPatch/CatcherPatch.apk], parent #1
Done dumping class loaders
Intern table: 87931 strong; 376 weak
JNI: CheckJNI is on; globals=727 (plus 43 weak)
Libraries: libandroid.so libcompiler_rt.so libjavacore.so libjavacrypto.so libjnigraphics.so libmedia_jni.so libmiuinative.so libopenjdk.so libqti_performance.so libsoundpool.so libwebviewchromium_loader.so (11)
Heap: 93% free, 1754KB/25MB; 50911 objects
Dumping cumulative Gc timings
Average major GC reclaim bytes ratio inf over 0 GC cycles
Average major GC copied live bytes ratio 0.0105241 over 681 major GCs
Cumulative bytes moved 12867064
Cumulative objects moved 168559
Peak regions allocated 253 (63MB) / 1024 (256MB)
Start Dumping histograms for 1 iterations for young concurrent copying
ScanImmuneSpaces: Sum: 9.844ms 99% C.I. 9.844ms-9.844ms Avg: 9.844ms Max: 9.844ms
ProcessMarkStack: Sum: 9.498ms 99% C.I. 9.498ms-9.498ms Avg: 9.498ms Max: 9.498ms
VisitConcurrentRoots: Sum: 5.391ms 99% C.I. 5.391ms-5.391ms Avg: 5.391ms Max: 5.391ms
ClearFromSpace: Sum: 1.043ms 99% C.I. 1.043ms-1.043ms Avg: 1.043ms Max: 1.043ms
GrayAllDirtyImmuneObjects: Sum: 889us 99% C.I. 889us-889us Avg: 889us Max: 889us
InitializePhase: Sum: 709us 99% C.I. 709us-709us Avg: 709us Max: 709us
ScanCardsForSpace: Sum: 484us 99% C.I. 484us-484us Avg: 484us Max: 484us
FlipOtherThreads: Sum: 413us 99% C.I. 413us-413us Avg: 413us Max: 413us
SweepSystemWeaks: Sum: 369us 99% C.I. 369us-369us Avg: 369us Max: 369us
VisitNonThreadRoots