4、获取ANR日志:adb命令,bugreport,开发者选项

要定位多媒体启动卡顿,第一步就是拿到ANR日志。这事说起来简单,但实际坑不少。我刚开始做性能优化时,就因为在紧急时刻用错了方式,白白浪费了半天时间。今天咱们就把三种主流方法聊透。

4.1 实时抓取:adb logcat 抓取 ANR 痕迹

最直接的方式就是 adb logcat。你可以在终端输入:

adb logcat -b events | grep -i "anr"

这会实时过滤events日志里的ANR事件。但有个问题——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 日志的三种路径

下图把三种方法的关系和输出整理了一下,便于你记忆:

获取 ANR 日志的三种路径 adb logcat 实时过滤 events bugreport 完整 Zip 包 显示所有ANR 自动写入 dropbox ANR 日志文件 traces.txt / dropbox > system_app_anr 堆栈分析 / 线程状态 建议:日常测试开启“显示所有ANR”,复现问题时先用 adb logcat 定位,最后用 bugreport 拉取完整现场。

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时就不慌了。