4、获取ANR日志:adb命令,bugreport,开发者选项
要定位多媒体启动卡顿,第一步就是拿到ANR日志。这事说起来简单,但实际坑不少。我刚开始做性能优化时,就因为在紧急时刻用错了方式,白白浪费了半天时间。今天咱们就把三种主流方法聊透。
4.1 实时抓取:adb logcat 抓取 ANR 痕迹
最直接的方式就是 adb logcat。你可以在终端输入:
adb logcat -b events | grep -i "anr"
这会实时过滤events日志里的ANR事件。但有个问题——ANR发生时日志刷得飞快,你一个走神可能就错过了关键行。
adb logcat -v threadtime -b events > event_log_$(date +%Y%m%d_%H%M%S).txt
这样即使没法实时看到,也可以事后搜“anr”或“am_anr”。我个人习惯同时开两个终端,一个抓events,一个抓main日志,方便互相印证。
4.2 拉取完整现场:bugreport 命令
真正遇到ANR时,我很少只靠logcat。完整方案是用 bugreport。它会生成一个压缩包,里面包含dumpsys、dmesg、trace文件、堆栈快照等全套信息。
adb bugreport bugreport_$(date +%Y%m%d_%H%M%S).zip
这个命令会花一点时间(30秒~2分钟不等),别以为它卡住了。生成完成后,zip文件会出现在当前目录下。解压后,重点看这两个文件:
FS/data/anr/traces.txt—— 所有ANR发生时的线程堆栈FS/data/system/dropbox/*anr*—— 系统记录的ANR信息
我曾经遇到过一个问题:bugreport 居然只抓到了部分anr文件。排查发现是因为设备空间快满了,系统自动清理了trace目录。所以抓日志前,最好先确认一下存储空间。
adb shell df -h /data
4.3 开发者选项:“显示所有ANR”
这个方法可能被很多人忽略。在开发者选项里,有一个开关叫 “显示所有ANR”(英文是 Show all ANRs)。开启后,即使后台应用产生ANR,系统也会弹出对话框,并把日志写入 dropbox,方便我们事后提取。
adb pull /data/system/dropbox/ 把整个dropbox目录拉下来,里面过滤 system_app_anr 开头的文件即可。这个方式的优点是带系统上下文,缺点是默认没开启。我建议你在测试机上一直开着,日常开发就能自动收集,而不必等到用户投诉。
4.4 三种方式对比——我选哪种?
| 方式 | 实时性 | 信息完整性 | 适用场景 | 坑点 |
|---|---|---|---|---|
| adb logcat -b events | 高 | 低(只有事件摘要) | 快速验证、知道大概时间点 | 日志被冲刷、需要手动grep |
| bugreport | 低(生成慢) | 高(完整dump) | 正式分析、提Bug、复现后的取证 | 生成时间长、占用空间大 |
| 开发者选项“显示所有ANR” | 中等 | 高(自动保存) | 长周期测试、无人值守收集 | 需提前打开开关,可能漏掉早期ANR |
我的经验是:先用 adb logcat 定位大概时间点,再用 bugreport 拉取完整现场。如果你在复现过程中,发现ANR不好再现,那就开“显示所有ANR”跑一晚上自动化测试,第二天直接拉dropbox目录。
4.5 知识体系:获取 ANR 日志的三种路径
下图把三种方法的关系和输出整理了一下,便于你记忆:
4.6 避坑指南——我曾经踩过的雷
- 日志被轮回覆盖: 连续多次ANR时,
traces.txt只会保留最后几个。我上次debug时只看到最后一次崩溃,前两次的堆栈全没了。后来我改用adb logcat -b events -v threadtime -f /sdcard/events_anr.txt提前把日志写到手机本地,防止被冲刷。 - bugreport 解压后找不到 anr 目录? 有的ROM会把ANR日志放在
dumpstate_board.txt里。别只盯着一个文件,多搜搜 “anr” 关键词。 - 开发者选项开启“显示所有ANR”后系统变卡: 是的,这个开关会增加写磁盘频率。我一般只在特定测试场景下才打开,跑完立刻关掉。
- adb 权限不够: 认领真机时,如果不是工程机或root过的设备,
adb pull /data/anr/traces.txt可能失败。可以尝试adb shell "cat /data/anr/traces.txt" > traces.txt,或者先adb shell logcat -d -b events > events.log把ANR事件转出来。
4.7 小结一下
这三种方式各有千秋。adb logcat 适合快速验证、bugreport 适合完整取证、开发者选项适合后台无人值守。拿到ANR日志只是第一步,下节课我们会重点解析 traces.txt 里的线程状态。不过今天把这些命令和技巧练熟,你遇到多媒体卡顿ANR时就不慌了。