1. 课程概述与背景:为什么需要 Crash 与 ANR 联动监控

做 Android 开发这些年,我遇到过不少奇奇怪怪的问题。Crash 和 ANR,大家都不陌生。但你真的把它们当「一家人」看待过吗?

我以前也以为,Crash 是崩溃,ANR 是卡死,分开处理就行。直到有一次线上事故——用户反馈 App 频繁闪退,日志只有几条 ANR 记录,没有 Crash。排查了两天,才发现 ANR 导致主线程卡死,系统杀进程,最终表现为「闪退」。嗯,这其实是一个联动问题。

今天这章,我们就聊聊为什么要把 Crash 和 ANR 放在一起监控。说白了,不懂联动,你的监控体系就是有盲区的。

1.1 两个「坏消息」的本质区别与联系

维度CrashANR
触发机制未捕获异常、信号崩溃主线程超时(5秒 / 10秒 / 30秒)
用户感知直接闪退弹框「无响应」,可选择等待或关闭
日志特征有崩溃堆栈有 traces.txt / 主线程堆栈
系统处理kill 进程 + 写入 crash logkill 进程 或 用户主动关闭
常见误区认为只要没 Crash 就是安全的认为 ANR 不影响用户体验

你看,两者触发点不同,但最终结果都可能让用户流失。而且,我经历过一个典型场景:ANR 往往是 Crash 的前兆。比如某个第三方 SDK 在主线程做了耗时操作,导致 ANR,紧接着又抛出异常,系统只记录了最后的 Crash,前面的 ANR 过程被淹没了。

1.2 为什么要联动?三个真实场景说服你

  • 场景一:静默 ANR 转 Crash
    用户没有点击「等待」,系统直接杀进程。此时你拿到的是 SIGKILL 或 Application Not Responding,但在很多监控平台里,它被归类为「System Crash」。你很难发现是 ANR 引发的连锁反应。
  • 场景二:多线程死锁
    我记得在一个金融类 App 项目中,主线程和一个后台线程同时持锁,导致死锁。主线程卡了 20 秒,最终发生 ANR。但日志里同时有两个线程的堆栈——如果只看 Crash,你根本找不到锁竞争的证据。我把 ANR 的 traces 和 Crash 堆栈拼在一起,才定位到问题。
  • 场景三:OOM 引发的假 ANR
    内存不足时,onStart 里的列表初始化耗时暴增。系统认为主线程超时,给出 ANR。实际上根因是内存泄漏造成的 GC 卡顿。如果你不把 ANR 和 Crash 的 OOM 数据联动,你会误解为「列表渲染太慢」。

核心观点:联动监控 = 把 ANR 当「半崩溃」事件,和 Crash 组成完整的事故链。单独处理任何一个,都会漏掉上下文。

1.3 当前行业的普遍痛点

我接触过不少团队。他们用了 Firebase、Bugly、Sentry 这些工具。但大多是这样的:

  1. Crash 走一套采集流程,ANR 走另一套采集流程
  2. 两个数据源存在不同平台,无法交叉分析
  3. 日志时间戳不一致,对不上号
  4. 归因到某个版本时,Crash 率降低了,ANR 率却上升了——没人去深挖反向关系

你想想看,如果连哪个操作先发生都搞不清楚,怎么优化?我曾经遇到一个项目,上线后 Crash 率 0.1%,看起来很健康。但 ANR 率达到 2%。用户评分只有 3.8。为什么?因为 ANR 虽然没让 App 直接闪退,但每次卡顿都消耗了用户耐心。

注意:不要以为 ANR 用户看不到。Android 系统会有弹框,但很多用户会直接切后台再回来,或者干脆杀掉进程——这种「软性退出」录不到正式 Crash 日志,只能靠 ANR 监控补上。

1.4 联动监控架构总览

下面这张图,是我在几个项目中沉淀下来的联动监控核心流程。你可以把它当作本章的「知识地图」。

Crash & ANR 联动监控架构图 分层结构:客户端采集 → 聚合归因 → 联动分析 → 告警修复 Crash 采集 Thread.setUncaught ANR 采集 FileObserver / 主线程监控 附加数据 内存 / 线程 / 堆栈快照 统一聚合层 时间对齐 · 线程堆栈融合 · 设备指纹 去重 & 关联 (同一进程 ID / 同一会话) 联动分析引擎 ANR → Crash 时序推理 · 锁竞争检测 · 内存趋势预警 根因分类矩阵(Crash主导 / ANR主导 / 混合) 告警 & 修复建议 线上大盘 & 趋势图 时间窗口 5s

1.5 你能从这门课学到什么?

这门课程不是给你一堆理论。我会把每个环节的落地方式、踩过的坑都讲清楚。具体包括:

  • 如何在客户端同时采集 Crash 和 ANR,且不互相干扰
  • 如何用统一 ID 把两个事件串起来(比如进程启动时间戳 + 自增序列)
  • 如何分析 traces.txt 和堆栈,判断到底是主线程死锁还是第三方库的锅
  • 如何写一个简单的联动分析脚本,自动给每个事故打标签
  • 如何利用联动结果制定优化优先级:先修 Crash 还是先修 ANR

一个小建议:在学习过程中,你最好手边有一个线上项目或者 Demo App。不需要多复杂,能模拟出 ANR 和 Crash 就行。跟着课程一步步把监控搭起来,效果比光看书好十倍。