【APP测试】04-手机日志、Crash、ANR 全流程手册

本文为个人学习整理笔记,仅用于技术交流与学习分享


咱们从「是什么→为什么→怎么用→遇到问题怎么办」,按标准流程来,可以一步不落跟着做✅


先回顾我们上一篇博客中的手机日志是什么?

一、先搞懂最基础:什么是手机日志记录?

解释

手机日志就是手机系统+APP的「全程黑匣子日记」 :你点按钮、发请求、闪退、卡死、报错......所有操作,手机都会默默记下来,存在日志里。

我们测试抓日志,就是翻这个日记,找APP为啥崩、为啥卡、为啥出问题。

为什么要学?

  • 你只说「APP闪退了」,开发根本不知道怎么改;
  • 你把日志甩过去,开发一眼就定位到哪行代码出问题,直接修BUG;
  • 不会抓日志=只能提表面BUG,会抓日志=专业测试,效率直接拉满。

二、先把两个核心BUG说透(测试天天见)

1. Crash 是什么?

解释 :APP直接闪退、突然消失、自己关掉 ,回到手机桌面。

比如你点一个按钮,APP直接没了,这就是 Crash(崩溃),是APP运行时发生了致命错误,系统强制把APP关掉了。

2. ANR 是什么?

解释 :APP卡死、点不动、按什么都没反应 ,手机弹出「应用无响应,等待/关闭」的弹窗。

比如你点按钮,APP转圈、没反应,最后弹框,这就是 ANR(Application Not Responding,应用无响应),是APP主线程被卡住,系统给用户的提示。


三、Crash 日志:从0到1全流程

1. Crash 日志是什么?

Crash日志就是APP闪退时,手机在logcat里记录的错误日记,里面写了「什么时候崩的、哪个APP崩的、为什么崩的、哪行代码崩的」,是定位闪退BUG的核心依据。

2. 为什么要抓Crash日志?

Crash是APP最严重的BUG之一,必须抓日志给开发,不然开发没法定位问题,只能靠猜。

3. 操作流程

前置准备(只做一次,后续不用重复)
  1. 安装好ADB环境,配置好系统环境变量(上一期有做过)
  2. 打开夜神模拟器(或插上真机,开启USB调试)
  3. 打开电脑CMD命令行窗口(Win+R输入cmd回车)
正式操作步骤
步骤 操作 命令 解释(为什么这么做)
1 连接夜神模拟器(真机跳过) adb connect 127.0.0.1:62001 给电脑和模拟器建立连接,电脑才能控制模拟器
2 确认设备连接成功 adb devices 检查设备是否真的连上了,避免后续命令报错 ✅ 出现127.0.0.1:62001 device就是成功
3 清空旧日志 adb logcat -c 把app中之前的垃圾日志全清掉,只抓最新的,避免旧日志干扰BUG定位
4 开始抓日志并保存到电脑 adb logcat -v time > D:\测试日志\crash_log.log -v time:给日志加时间戳,对应操作时间 >:把日志存到电脑D盘,方便后续分析
5 复现Crash闪退 操作APP,让它闪退一次 必须在抓日志期间复现,日志才会记录闪退信息
6 停止抓日志 Ctrl + C 结束日志抓取,CMD会恢复可输入状态
7 分析日志找BUG 打开D:\测试日志\crash_log.log 搜关键词,定位崩溃日志
8 给开发提BUG 截图+发日志文件 把完整崩溃日志发给开发

按照上述的步骤那么咱们做的截图如下所示:

ctrl+c停止抓取日志

得到的日志文件如图:

4. 日志里找什么?(只认关键词,不用懂代码)

打开日志文件,直接搜这几个关键词,搜到就是Crash日志:

  1. exception(异常,核心关键词)
  2. fatal / FATAL EXCEPTION(致命异常,APP崩溃的标志)
  3. caused by(崩溃的根本原因)
  4. force finish / force finishing(系统强制关闭APP)

5. 模拟真实Crash日志

log 复制代码
04-11 15:30:22.123  E/AndroidRuntime(1234): FATAL EXCEPTION: main
04-11 15:30:22.123  E/AndroidRuntime(1234): Process: com.example.testapp, PID: 1234
04-11 15:30:22.123  E/AndroidRuntime(1234): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
04-11 15:30:22.123  E/AndroidRuntime(1234): 	at com.example.testapp.MainActivity.onClick(MainActivity.java:50)
04-11 15:30:22.123  E/AndroidRuntime(1234): 	at android.view.View.performClick(View.java:7125)
04-11 15:30:22.123  E/AndroidRuntime(1234): 	at android.view.View$PerformClick.run(View.java:27448)
解读:
  • E/:错误级别,代表这条是报错日志
  • FATAL EXCEPTION:APP发生致命异常,直接崩溃了
  • com.example.testapp:被测APP的包名,确认是你测的APP
  • NullPointerException:空指针异常,最常见的闪退原因
  • MainActivity.java:50:第50行代码出问题,开发直接定位
给开发的截图/话术:

【BUG描述】点击「提交」按钮,APP发生Crash闪退

【复现步骤】1. 打开APP 2. 进入订单页 3. 点击「提交」按钮 4. APP直接闪退

【日志说明】已抓取Crash日志,出现FATAL EXCEPTION,详见附件

【附件】crash_log.log + 崩溃日志截图

6. 遇到问题怎么办?

  • 问题1:adb devices没设备
    解决:执行adb kill-serveradb start-server重启ADB服务,再重新连接
  • 问题2:日志里找不到关键词
    解决:复现BUG太慢,日志被环形缓冲区覆盖了,复现要快,抓日志要及时
  • 问题3:日志里有很多系统日志,找不到APP的
    解决:按包名过滤,只看你APP的日志,比如adb logcat com.example.testapp *:E

四、ANR 日志:从0到1全流程

1. ANR 日志是什么?

ANR日志是APP卡死时,手机记录的两类信息

  1. logcat里的ANR触发提示(快速定位)
  2. /data/anr/traces.txt系统文件(核心,记录卡死瞬间的线程信息)

2. 为什么要抓ANR日志?

ANR是APP体验极差的BUG,必须抓日志给开发,定位主线程阻塞的原因(比如死锁、耗时操作)。

3. 操作流程

前置准备(同Crash)
  1. 打开CMD,连接夜神/真机,adb devices确认在线
正式操作步骤
步骤 操作 命令 解释(为什么这么做)
1 清空旧日志 adb logcat -c 清掉旧日志,避免干扰
2 开始抓ANR日志 adb logcat -v time > D:\测试日志\anr_log.log 带时间戳,存到电脑,记录ANR触发过程
3 复现ANR卡死 操作APP,让它卡死弹出ANR弹窗 必须在抓日志期间复现
4 停止抓日志 Ctrl + C 结束抓取
5 立即导出ANR核心文件 adb pull /data/anr/traces.txt D:\测试日志\ traces.txt只存最后一次ANR,必须第一时间导出,否则会被新ANR覆盖(手机里根本没有这个 traces.txt 文件 → 说明最近没有发生 ANR 崩溃)
6 分析日志找BUG 打开anr_log.logtraces.txt 搜关键词,定位ANR
7 给开发提BUG 发日志+文件 把logcat和traces.txt都发给开发

日志文件

4. 日志里找什么?(只认关键词)

① logcat里的ANR关键词
  • ANR
  • Input dispatching timed out(输入超时,最常见)
  • ANR in 包名
模拟ANR logcat日志:
log 复制代码
04-11 15:35:10.456  E/ActivityManager(  500): ANR in com.example.testapp (com.example.testapp/.MainActivity)
04-11 15:35:10.456  E/ActivityManager(  500): PID: 1234
04-11 15:35:10.456  E/ActivityManager(  500): Reason: Input dispatching timed out (Waiting to send key event because the focused window has not finished processing all of the input events that were previously delivered to it.)
04-11 15:35:10.456  E/ActivityManager(  500): Load: 1.2 / 1.1 / 1.0
解读:
  • ANR in com.example.testapp:你的APP发生了ANR
  • Input dispatching timed out:输入事件超时,主线程被卡住了
  • 时间戳对应你操作的时间,确认是这次复现的BUG
② traces.txt里的ANR信息

traces.txt里重点看 主线程(main thread)的栈信息,开发用它定位阻塞的代码,小白不用懂,直接把文件发给开发就行。

5. 给开发的截图/话术:

【BUG描述】连续点击「刷新」按钮,APP发生ANR无响应,弹出「应用无响应」弹窗

【复现步骤】1. 打开APP 2. 进入列表页 3. 连续点击「刷新」按钮 4. APP卡死,弹出ANR弹窗

【日志说明】已抓取logcat日志和traces.txt文件,详见附件

【附件】anr_log.log + traces.txt + ANR日志截图

6. 遇到问题怎么办?

  • 问题1:adb pull traces.txt报错权限不足
    解决:模拟器需要开启root权限,真机需要root,夜神模拟器在设置里开启root即可
  • 问题2:traces.txt里没有ANR信息
    解决:ANR发生后没有第一时间导出,被新的ANR覆盖了,必须复现后立刻pull
  • 问题3:想查历史ANR
    解决:traces.txt只存最后一次,需要导出/data/system/dropbox下的文件,里面存了一段时间内的所有异常

五、Crash & ANR 核心区别(一张表看懂)

对比项 Crash(崩溃) ANR(无响应)
现象 APP直接闪退、消失 APP卡死、点不动,弹无响应框
日志位置 仅logcat logcat + /data/anr/traces.txt
核心关键词 FATAL EXCEPTIONexceptioncaused by ANRInput dispatching timed out
日志特点 实时打印,环形缓冲区覆盖 traces.txt只存最后一次,需第一时间导出
核心原因 代码发生致命错误 主线程阻塞、耗时操作、死锁

六、小白速记口诀(刻在脑子里)

Crash 口诀

先开CMD → 连设备 → 清日志 → 抓日志 → 复现闪退 → 找FATAL EXCEPTION → 给开发

ANR 口诀

先开CMD → 连设备 → 清日志 → 抓日志 → 复现卡死 → 找ANR → 立刻pull traces.txt → 给开发


七、补充:DropBox 日志(了解)

  • 路径:/data/system/dropbox
  • 作用:批量存储一段时间内的所有ANR、Crash,弥补traces.txt只能存最后一次的不足
  • 命令:adb pull /data/system/dropbox D:\测试日志\
  • 适用场景:需要查历史异常、traces.txt被覆盖时用,日常测试用不到

以上就是整理的手机日志(Crash/ANR)抓取的全流程笔记啦,如果对你有帮助,记得点赞❤️、收藏📥、关注不迷路,咱们下期不见不散哟😘!

相关推荐
闽农2 个月前
Android ANR 调用栈溯源
android·anr
千里马学框架3 个月前
疑难ANR面试题:crash导致ANR深入剖析
android·智能手机·framework·perfetto·性能·anr·小米汽车
齊家治國平天下4 个月前
Android 14 系统中 Tombstone 深度分析与解决指南
android·crash·系统服务·tombstone·android 14
丁劲犇4 个月前
Visual C++下使用Win32 API为Release模式导出崩溃堆栈
c++·windows·crash·dump·离线调试·vc·崩溃堆栈
赖small强4 个月前
【Linux C/C++开发】Linux 系统野指针崩溃机制深度解析
linux·mmu·crash·core dump·野指针
0xAaron4 个月前
确定crash文件和dSYM是否对应
ios·uuid·crash·dsym
齊家治國平天下7 个月前
Android 14 系统 ANR (Application Not Responding) 深度分析与解决指南
android·anr
tran_sient7 个月前
【Android】制造一个ANR并进行简单分析
android·anr
EngZegNgi9 个月前
安卓应用启动崩溃的问题排查记录
android·crash·启动崩溃