第1章:Crash治理概述

什么是Crash?

咱们做 Android 的,没人没遇到过 Crash。说白了,就是你的 App 在执行一段代码时,遇到了它无法处理的情况,然后直接“罢工”了。更技术一点的说法:Crash 是程序运行时产生了未捕获的异常,或者收到了操作系统发出的致命信号,导致进程被强制终止。

我记得刚入行时,有个同事的 App 总在某个页面闪退,查了好久才发现是空指针。那种挫败感,相信大家都懂。

Crash 主要分两类:

  • Java Crash:由 Java 或 Kotlin 代码抛出的未捕获异常引发,比如 NullPointerException、IndexOutOfBoundsException。最常见,也好定位。
  • Native Crash:发生在 C/C++ 层面,由 signal 触发,比如 SIGSEGV(段错误)、SIGABRT(中断)。多跟 JNI、So 库相关,排查起来比较头疼。

看看这个分类表,能帮你快速判断问题类型:

Crash 类型 触发机制 典型错误 排查难度
Java Crash 未捕获异常 (Throwable) NullPointerException ★☆☆
Native Crash 系统信号 (signal) Segmentation fault ★★★

我个人的小习惯:接到 Crash 反馈,先看日志里有没有 Exception 字眼。如果有,基本是 Java 层问题;如果只有一堆内存地址和寄存器信息,那八成是 Native 挂了。

Crash 的影响

一个 Crash 看似是代码层面的小故障,但它带来的连锁反应,往往超出预期。我见过一个很典型的案例:某个版本因为一个空指针导致启动页频繁闪退,用户反馈差评率一度飙到 30%,直接影响了当月的新增用户量。

具体来说,Crash 的影响体现在以下几个方面:

  1. 用户体验断崖式下跌——用户正刷着视频,突然 App 闪退。一次两次还能忍,频繁出现,用户大概率会卸载。
  2. 业务数据直接受损——关键页面(比如支付、下单)发生 Crash,意味着转化率下降,真金白银的流失。你想想看,一个支付流程在最后一步崩溃,用户会怎么想?
  3. 开发效率被拖垮——线上 Crash 频发,团队不得不花大量时间排查、打补丁、发紧急修复版本。我曾在项目中连续两周都在修线上问题,新功能根本推不动。
  4. 品牌口碑受损——App Store 或应用市场的差评,哪怕只有几十条,也足以劝退潜在用户。很多用户并不会给你第二次机会。

核心观点:Crash 治理不是「锦上添花」,而是「雪中送炭」。一个稳定的 App,才是用户体验和商业转化的基础。

治理目标与原则

搞清楚了 Crash 是什么,以及它有多痛,我们再来聊聊怎么治。我个人习惯把 Crash 治理分成三个层次:

  • 零闪退——听起来很理想化,但应该是我们追求的最终目标。尤其是核心路径(启动、登录、支付),要做到极致稳定。
  • 快速发现——Crash 不能被用户先发现。通过监控系统,在用户反馈前就收到告警。我曾经因为晚发现了一个线上 Crash,导致用户投诉累积了整整一个周末,真的很被动。
  • 根源治理——不要只打补丁,要从代码层面、流程层面解决问题。比如空指针,可以用 Kotlin 的 null safety 特性,或者团队定个规范:所有可能的 null 值都必须显式处理。
  • 自动恢复——对于非致命异常,可以考虑通过 UncaughtExceptionHandler 做一些兜底处理,比如重启 App 或者引导用户反馈。但这招要慎用,不能掩盖真正的 bug。

治理原则,我提炼了四个字:「防、快、准、改」。

  • 防:代码审查、静态检测、单元测试,把问题扼杀在开发阶段。
  • 快:建立实时监控和告警体系,Crash 发生后 5 分钟内通知到人。
  • 准:精确归因,能定位到具体行号、堆栈、设备、系统版本。
  • 改:不仅修复 Crash,还要改进开发流程,避免同类问题再次发生。

避坑指南:我曾经接手过一个项目,线上 Crash 率很高,但团队只盯着监控数字看,从不回头复盘。结果就是每个版本都在修旧 bug,新 bug 又不断出现。后来我们强制要求:每个 Crash 修复后,必须写一份根因分析文档,并在团队内分享。效果立竿见影。

这其实就是 Crash 治理的完整闭环。从预防到发现,再到修复和复盘,缺一不可。下面这张图可以帮你快速理解这个体系:

Android Crash 治理知识体系 Java Crash Native Crash Crash 分类 Crash 的影响 用户体验下降 业务数据受损 开发效率拖累 治理流程(闭环) 预防 发现 修复 复盘 持续反馈,改进流程 核心原则:防、快、准、改