Android稳定性-49-Android 版本准入标准:稳定性指标、阻断项与灰度建议

Android 版本准入最容易发生争议的地方,不是测试有没有发现问题,而是发现问题之后版本还能不能继续走。研发会说修复已经合入,项目会说发布时间不能再推,测试会说长稳还有异常,产品会说用户路径不能受影响。如果没有事先约定的准入口径,所有讨论都会在版本后期变成拉扯。

准入标准的价值,是把“能不能进下一阶段”从临场判断变成工程判断。它要求团队在版本开始前就定义好稳定性指标、阻断项、灰度条件、遗留问题审批方式和回滚触发条件。到了评审时,大家不是重新争论价值观,而是对照证据判断当前版本是否满足门槛。

这篇讲 Android 稳定性版本准入,不讨论功能需求是否完整,也不讨论产品体验验收。重点放在 Crash、ANR、重启、卡死、功耗、温升、内存、I/O、核心链路和灰度风险这些会直接影响版本可靠性的内容。

一、准入不是测试结束,而是阶段切换

很多团队把准入理解成测试报告里的最后一页:通过、不通过、建议发布。这个理解太晚了。真正的准入应该出现在多个阶段之间。

开发自测进入集成测试,需要一套冒烟准入。集成测试进入稳定性长稳,需要一套系统准入。稳定性长稳进入灰度,需要一套风险准入。灰度进入全量发布,需要一套线上准入。每一次准入的目标不同,指标也不应该完全相同。

阶段 准入目标 关注重点 典型结论
冒烟准入 包可测 开机、解锁、网络、安装、核心 App 启动 可进入系统测试
稳定性准入 包可压 Crash、ANR、重启、资源泄漏、核心专项 可进入长稳
灰度准入 风险可控 Top Issue、修复验证、指标基线、回滚方案 可小流量发布
全量准入 规模可放大 灰度趋势、线上告警、售后诊断、遗留审批 可扩大发布

准入不是证明版本完美,而是证明当前阶段的主要风险已经被识别并降到可接受范围。这个“可接受”必须提前定义,否则每次都会变成主观判断。

二、稳定性指标要分层

版本准入不能只看一个总分。Android 稳定性问题跨 App、Framework、Native、HAL、Kernel 和硬件环境,指标要分层看。

第一层是硬阻断指标,出现就不能继续推进,例如无法开机、随机重启、system_server Watchdog、OTA 后无法进入桌面、核心路径必现 ANR、数据丢失。第二层是趋势指标,例如 Crash 率、ANR 率、重启率、启动耗时、功耗、温升、内存增长。第三层是覆盖指标,例如长稳时长、设备数量、场景覆盖、弱网低电量低存储等极限场景。第四层是诊断指标,例如 bugreport 可导出、dropbox 记录完整、线上 crash 上报可用、回滚链路可用。

指标层级 示例 准入口径 说明
硬阻断 Watchdog、kernel panic、开机失败 不允许遗留 除非确认非版本问题且有证据
趋势指标 Crash/ANR/重启率 不高于基线或目标线 要和上一稳定版本比较
覆盖指标 设备数、时长、场景 达到计划样本 覆盖不足时不能给强结论
诊断指标 日志、告警、回滚 链路可用 灰度和量产尤其重要

指标分层后,评审会可以更快聚焦:硬阻断先判定是否清零,趋势指标看是否回到基线,覆盖指标看结论是否可信,诊断指标看带风险发布后能否发现和止损。

三、指标阈值不能脱离基线

很多准入表会写“Crash 率小于 0.1%”“ANR 率小于 0.05%”。这种绝对值有用,但不够。不同产品、不同设备、不同用户路径、不同统计口径差异很大,只看绝对阈值容易误判。

更稳妥的方式是同时看目标线和基线。目标线来自质量要求,基线来自上一稳定版本或同平台成熟版本。如果新版本指标低于目标线但明显劣化,仍然要解释;如果新版本略高于目标线但和历史基线一致,也要看用户影响和灰度策略。

准入评审时建议展示四个数:当前版本、上一稳定版本、同批设备历史均值、目标门槛。

指标 当前版本 上一稳定版本 目标门槛 判断
Java Crash 率 0.07% 0.05% <=0.08% 目标内但劣化,需要解释新增模块
ANR 率 0.018% 0.021% <=0.03% 可接受
非预期重启 2/5000h 0/5000h 0 阻断,需要根因或排除证据
相机打开失败 0.12% 0.03% <=0.05% 阻断灰度,主路径劣化

这张表的作用不是让数字看起来专业,而是避免只用一个指标讲故事。版本准入要能回答“和谁比、差多少、为什么、能不能接受”。

四、阻断项要提前写死

阻断项必须在版本开始前约定,不能等到问题发生后再讨论是否阻断。否则每个阻断项都会被项目压力重新解释。

Android 稳定性常见阻断项可以分成几类。

系统可用性类:无法开机、卡开机动画、频繁重启、OTA 后无法启动、恢复出厂设置失败。核心服务类:system_server Watchdog、SurfaceFlinger 死亡、servicemanager 异常、关键 native service 反复 crash。用户主路径类:通话失败、相机无法打开、导航定位异常、支付扫码失败、蓝牙车机断连。数据安全类:升级后数据丢失、应用数据异常清除、文件系统错误。诊断止损类:无法导出日志、灰度告警不可用、回滚失败。

阻断项不代表永远不能放行,但放行必须走例外审批。例外审批要写清楚原因、影响范围、规避方案、灰度门槛、回滚触发和责任人。没有这些信息,所谓例外就是绕过准入。

五、灰度建议不是一句“建议小流量”

灰度准入需要更具体。小流量是多少,覆盖哪些设备,观察多久,看哪些指标,触发什么动作,这些都要写清。

例如一个相机相关版本,如果前期出现过相机 Top Issue,即使修复验证通过,灰度策略也不应该只写“先 5%”。更合理的写法是:第一阶段 1%,仅覆盖 A03/A04 非运营商定制渠道,观察 24 小时;相机打开失败率不得高于上一版本 1.2 倍;新增 provider timeout 超过 3 次或 Crash 率超过门槛立即停止;第二阶段 5%,增加扫码和视频通话埋点观察;第三阶段再扩大到 20%。

灰度阶段 流量 观察时长 重点指标 停止条件
G1 1% 24h Crash、ANR、重启、相机失败率 任一硬阻断出现
G2 5% 48h 主路径专项指标、Top Issue 关键日志 指标超过基线 1.5 倍
G3 20% 72h 售后反馈、功耗、温升、区域差异 趋势持续劣化
G4 全量 持续监控 总体稳定性和回滚指标 达到回滚条件

灰度建议写得具体,线上团队才能执行,版本 owner 才能承担决策。

六、完整案例:一个准入评审如何判断是否放行

假设 V5.4.0 是一个 Android 13 平台维护版本,主要改动包括相机 HAL 更新、蓝牙协议栈补丁、系统桌面性能优化和安全补丁。版本计划进入 5% 灰度。

准入前,测试结果如下:80 台设备完成 72 小时长稳,Java Crash 率 0.06%,ANR 率 0.02%,均在目标线内;发现 1 次非预期重启,pstore 显示 subsys-restart: modem,同设备在上一版本也出现过相似记录;相机冷启动专项 4000 次无黑屏,但日志中仍有 2 次 provider close 超时;蓝牙车机连接 300 轮有 1 次回连超过 20 秒;Top Issue 里相机黑屏已关闭,蓝牙回连慢仍为 Watch。

如果只看“长稳通过”,这个版本似乎可以灰度。如果只看“出现过重启”,又可能直接阻断。准入评审要把证据放到规则里判断。

第一,非预期重启属于硬阻断候选,但证据显示是 modem 子系统重启,且同设备历史版本也出现过,当前版本没有新增 modem 相关改动。评审结论不是直接忽略,而是要求补充 20 台同批设备 24 小时 modem 压力和基带日志,若无新增再允许进入 G1。第二,相机 Top Issue 已有修复验证,但 provider close 超时日志仍出现,说明风险没有完全消失,灰度必须增加相机打开失败率和 provider timeout 监控。第三,蓝牙回连慢命中车机路径,但概率低且有自动恢复,允许进入 Watch,不过 G1 阶段要限制车机渠道设备比例。

最终准入结论可以这样写:

1
2
3
4
5
准入结论:允许进入 G1 灰度,不允许直接扩大到 5%。
前置条件:补充 modem 压力 20 台 x 24h,未出现新增非预期重启;相机 provider timeout 监控上线。
灰度范围:1%,A03/A04 普通渠道,暂不覆盖车机重度用户标签。
停止条件:任一非预期整机重启;相机打开失败率超过上一版本 1.5 倍;蓝牙回连失败率连续 6 小时劣化。
复评时间:G1 24 小时后。

这个案例说明,准入不是简单的通过或不通过。它可以给出带条件的阶段性结论,但条件必须可执行、可监控、可回滚。

七、准入命令和数据提取模板

准入材料需要能追溯数据来源。下面这些命令适合在准入前抽查版本、日志和设备状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 版本身份
adb shell getprop ro.build.fingerprint
adb shell getprop ro.build.version.incremental
adb shell getprop ro.vendor.build.fingerprint

# 系统异常概览
adb shell dumpsys dropbox --print > dropbox.txt
adb logcat -b crash -d -v threadtime > crash.log
adb logcat -b events -d -v threadtime > events.log

# ANR / traces 线索
adb shell ls -lt /data/anr 2>/dev/null
adb shell dumpsys activity processes > activity_processes.txt

# 重启和内核异常
adb shell getprop ro.boot.bootreason
adb shell ls /sys/fs/pstore 2>/dev/null
adb shell cat /proc/last_kmsg 2>/dev/null | head

# 资源趋势抽样
adb shell dumpsys meminfo > meminfo_all.txt
adb shell dumpsys batterystats --charged > batterystats.txt
adb shell dumpsys thermalservice > thermal.txt

如果准入数据来自多台设备,可以固定一个 CSV 模板:

1
2
serial,model,build,hours,java_crash,anr,reboot,camera_fail,bt_fail,top_issue_hit,result,note
<serial>,<model>,<build>,<hours>,<count>,<count>,<count>,<rate>,<rate>,<yes/no>,<pass/fail>,<note>

这个模板看起来简单,但能保证准入会上每个指标都有设备、版本和样本量。

八、准入报告要写判断,不只写数据

准入报告不是把所有测试结果堆上去。它要把数据转换成判断。

建议报告正文按五段写。第一段写版本范围,包括 build、机型、渠道、关键改动。第二段写测试覆盖,包括设备数、时长、场景、专项和未覆盖项。第三段写指标结果,包括硬阻断、趋势指标和与基线对比。第四段写 Top Issue 和遗留风险,包括关闭情况、Watch 项和例外审批。第五段写准入结论,包括是否进入下一阶段、前置条件、灰度门槛和回滚条件。

不要把“不通过项为 0”当成充分结论。稳定性准入更关心未覆盖风险和趋势变化。如果某个专项没跑、某个机型样本不足、某条日志链路不可用,也应该写进报告。诚实暴露边界,比给出漂亮结论更有工程价值。

九、常见误判

第一,把功能冒烟通过当成稳定性准入通过。功能可用只能说明包能跑,不能说明长时间、压力、极限和灰度下可靠。

第二,只看当前版本指标,不看历史基线。指标在门槛内但明显劣化,仍然可能说明新风险。

第三,把 Top Issue 关闭数当成唯一依据。Top Issue 都关闭了,也可能存在覆盖不足、监控缺失或灰度止损能力不足。

第四,把灰度当成补测试。灰度是验证风险放大后的真实表现,不应该替代实验室里必须完成的基础验证。

第五,例外放行没有停止条件。带风险发布并不可怕,可怕的是没有监控和回滚触发,只能等用户投诉。

十、检查清单

准入评审前建议逐项确认:

  • build fingerprint、渠道包、OTA 包和测试包是否一致。
  • 稳定性测试设备数、时长和场景是否达到计划。
  • Crash、ANR、重启、Watchdog、Native Crash 是否与基线对比。
  • 所有硬阻断项是否清零,未清零项是否有例外审批。
  • Top Issue 是否全部有关闭结论或灰度观察策略。
  • 遗留问题是否写明影响范围、规避方案和 owner。
  • 灰度指标、观察窗口、停止条件和回滚方案是否明确。
  • 日志采集、线上告警、售后导出和问题上报链路是否可用。
  • 未覆盖场景是否明确写入结论,避免被误读为已验证。
  • 准入结论是否能被执行,而不是只写“建议发布”。

十一、输出物模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Android 稳定性版本准入评审

## 1. 版本信息
- 产品 / 机型:<product / model>
- Build:<fingerprint / incremental>
- 阶段:<冒烟 / 稳定性 / 灰度 / 全量>
- 关键变更:<模块和风险点>

## 2. 覆盖情况
| 项目 | 计划 | 实际 | 结论 |
| --- | --- | --- | --- |
| 长稳设备数 | | | |
| 长稳时长 | | | |
| 核心专项 | | | |
| 极限场景 | | | |

## 3. 稳定性指标
| 指标 | 当前版本 | 历史基线 | 门槛 | 判断 |
| --- | --- | --- | --- | --- |
| Java Crash | | | | |
| ANR | | | | |
| 重启 | | | | |
| Watchdog | | | | |

## 4. Top Issue 与遗留风险
| Issue | 等级 | 状态 | 准入影响 | 后续动作 |
| --- | --- | --- | --- | --- |

## 5. 准入结论
- 结论:<通过 / 不通过 / 带条件进入下一阶段>
- 前置条件:<必须先完成的动作>
- 灰度策略:<流量、范围、观察窗口>
- 停止条件:<触发即暂停或回滚>
- 责任人:<版本 owner / 测试 owner / 研发 owner>

十二、准入口径如何落到流水线

准入标准如果只存在评审文档里,执行会依赖人工记忆。更稳妥的做法,是把一部分准入口径前移到构建流水线、自动化测试平台和质量看板中。不是所有判断都能自动化,但硬指标、覆盖指标和明显阻断项应该尽量自动提醒。

比如构建完成后,流水线可以自动记录 build fingerprint、vendor fingerprint、安全补丁、预置应用差异;稳定性任务结束后,平台自动汇总 Crash、ANR、reboot、Watchdog、Native Crash、测试时长、设备离线率;准入看板根据门槛标红。这样评审会就不用从零整理数据,而是专注解释异常和做决策。

准入项 自动化来源 人工复核点
build 身份 构建系统、设备 getprop 测试包和发布包是否一致
Crash/ANR logcat、dropbox、上报平台 是否为新增、是否命中主路径
重启 bootreason、pstore、测试平台 是否硬件、环境或版本引入
覆盖率 任务系统、设备池 样本是否代表目标渠道
Top Issue 缺陷系统、风险台账 等级和关闭条件是否合理

落到流水线时要注意一个边界:自动化结果可以给出红黄绿状态,但不能替代例外审批。比如一次重启被平台标红后,仍然需要工程证据判断是否为外部电源中断、单台硬件故障或真实版本问题。自动化负责让问题不被漏掉,人工负责解释证据和承担决策。

十三、遗留风险审批要有硬格式

版本准入经常遇到“问题还没完全关闭,但希望进入下一阶段”。这不是绝对不允许,但必须有审批格式。没有格式,遗留风险就会变成口头承诺。

遗留风险审批至少要写六件事:遗留原因、影响范围、用户后果、规避或修复计划、监控方式、停止条件。遗留原因不能只写“时间不足”,要说明为什么当前阶段无法完全修复,是根因未明、修复风险过高、验证窗口不足,还是需要外部供应商支持。影响范围要尽量量化,不能只写“少量用户”。停止条件要能执行,比如指标超过基线 1.5 倍、同类问题新增 3 起、出现主路径失败、售后投诉达到阈值。

1
2
3
4
5
6
7
8
9
10
11
# 遗留风险审批
- 问题:<issue id / title>
- 当前等级:<Critical / Watch / Follow>
- 遗留原因:<为什么不能在当前阶段完全关闭>
- 影响范围:<机型、渠道、场景、概率>
- 用户后果:<用户会看到什么,是否有数据或安全风险>
- 规避方案:<用户侧、服务端、配置、回滚等>
- 监控方式:<指标、日志、告警、负责人>
- 停止条件:<触发后暂停灰度或回滚>
- 最晚关闭时间:<日期 / 版本>
- 审批人:<版本 owner / 质量 owner / 研发 owner>

审批格式的意义,是让带风险进入下一阶段这件事透明化。它不是为了制造阻力,而是为了避免风险在口头上被低估。

十四、灰度复评要看趋势拐点

灰度开始后,准入工作没有结束。G1、G2、G3 每次扩大前都应该复评。复评不是重复准入报告,而是看趋势有没有发生拐点。

趋势拐点包括:Crash 或 ANR 从稳定变成持续上升;某个机型明显高于其他机型;某个区域或渠道异常集中;Top Issue 相关关键字重新出现;售后反馈和日志指标指向同一链路。只要出现拐点,即使总体指标还没超过门槛,也应该暂停扩大,先解释原因。

复评表可以很短:

项目 G1 结果 G2 前判断 动作
总 Crash 率 0.05%,持平 可接受 继续观察
相机失败率 0.04%,高于基线 1.3 倍 接近门槛 扩大前补查关键日志
重启 0 可接受 继续
售后反馈 2 起蓝牙回连慢 与 Watch 项相关 限制车机用户扩大

灰度复评要和停止条件绑定。否则团队会陷入“再观察一天”的惯性,等到指标明显恶化时已经扩大了流量。

十五、准入标准也需要版本化

准入标准本身不是一成不变的。产品进入不同生命周期,平台从 Android 13 升到 Android 14,硬件从 EVT 到 DVT 再到 MP,指标门槛都可能调整。标准如果没有版本化,评审时就会出现“以前就是这么放的”和“现在要求更高”的争议。

建议准入标准像代码一样维护版本。每次调整门槛、增加阻断项、修改灰度策略,都记录原因和生效范围。比如某次线上出现 OTA 后开机慢,就应该把 OTA 首启耗时加入后续准入;某次售后发现日志缺字段,就应该把日志字段完整性加入诊断准入。

准入标准版本化以后,团队可以追溯为什么某个版本按某个口径放行,也能持续把事故经验转成规则。这是质量体系成熟的重要标志。

十六、不同角色在准入中的职责

准入评审不能只有测试团队发言。稳定性测试能提供证据,但发布决策需要多个角色共同承担。版本 owner 负责判断阶段节奏和发布动作,研发 owner 负责解释根因、修复风险和遗留影响,测试 owner 负责说明覆盖、证据和未覆盖边界,质量 owner 负责守住准入口径和例外审批,运维或线上 owner 负责确认监控、灰度和回滚能力。

职责不清时,准入会常见两种问题:一种是测试被迫独自承担是否发布的判断,另一种是所有人都认可风险但没人给出动作。比较好的做法是把职责写进准入模板。比如硬阻断未清零时,质量 owner 有权要求不进入下一阶段;修复风险不明时,研发 owner 必须给出替代方案;灰度停止条件不具备时,版本 owner 不能批准扩大。

角色 准入前输入 评审中责任 评审后动作
测试 owner 覆盖、指标、Top Issue、未覆盖项 说明证据和结论边界 跟踪补测和回归
研发 owner 根因、修复、风险、遗留说明 解释技术判断 按截止时间交付修复或排除证据
版本 owner 阶段计划、灰度范围、发布时间 做发布动作选择 执行暂停、扩大或回滚
质量 owner 标准、阻断项、例外流程 维护准入口径 归档结论并更新规则
线上 owner 看板、告警、回滚链路 说明止损能力 监控灰度和输出复评

准入结论也应该按角色拆解动作。只写“同意灰度”不够,还要写谁负责打开灰度、谁看相机指标、谁处理蓝牙 Watch 项、谁在指标超限时发起暂停。

十七、准入数据要保留可追溯证据包

准入材料经常在发布后才被重新翻出来。出了线上问题,团队需要回看当时为什么放行、哪些数据支撑了结论、哪些风险被标记为遗留。如果准入报告只有截图或口头纪要,事后很难复盘。

建议每次准入生成一个证据包,至少包含测试报告、原始指标 CSV、Top Issue 台账、遗留审批、关键日志索引、灰度策略和会议结论。证据包目录可以按版本和日期组织,文件名写清阶段。

1
2
3
4
5
6
7
8
release_gate/V5.4.0/G1_20260418/
build_info.txt
stability_metrics.csv
top_issues.md
residual_risks.md
evidence_index.md
grey_strategy.md
review_minutes.md

证据包不是为了增加文档负担,而是为了让准入结论能被审计和复盘。尤其是带条件灰度的版本,后续每次扩大都应该引用上一阶段证据包,并说明哪些条件已经满足,哪些风险仍在观察。

十八、准入失败也要形成结论

准入失败不能只说“不通过”。不通过的结论也要可执行。它应该写明失败原因、阻断项、必须完成的修复、补测范围、下一次复评时间和责任人。

比如一个版本因为非预期重启不准入,结论不能停在“存在重启风险”。更好的写法是:不允许进入 G1。阻断项为 A06 设备 2/3000h 非预期重启,bootreason 指向 kernel panic,pstore 已归档。BSP owner 需在 4 月 20 日 18:00 前给出根因或排除证据;修复包需完成 A06 30 台 x 48h 高负载长稳,且无同类 pstore。复评时间 4 月 21 日 10:00。

失败结论清楚,团队才能围绕同一个目标推进。否则不通过会被理解成测试态度保守,而不是一组待满足的工程条件。

十九、准入结论的表达要避免含混

准入结论最忌讳含混。比如“基本通过,后续关注”“原则同意发布”“风险可接受”这类表达,在会议上听起来顺滑,落到执行时却很难判断下一步。清楚的结论应该包含动作、范围、条件、观察窗口和责任人。

可以把结论固定成四种:通过、不通过、带条件进入下一阶段、延期复评。通过也要写范围,比如只通过 A03/A04 公开渠道,不代表所有渠道。带条件进入下一阶段要写前置条件和停止条件。延期复评要写复评时间和必须补齐的证据。这样每个角色都知道自己该做什么。

1
2
3
4
5
6
结论表达示例:
结论:带条件进入 G1。
范围:A03/A04 公开渠道 1%,暂不覆盖运营商定制版。
前置条件:相机 provider timeout 监控上线,蓝牙 Watch 项补充 24h 车机回连数据。
停止条件:出现任一非预期重启;相机失败率超过基线 1.5 倍;同类售后反馈超过 5 起。
复评:G1 满 24 小时后由版本 owner、测试 owner、线上 owner 共同复评。

准入结论写得硬,后续执行才不会靠个人理解。稳定性质量管理里,很多风险不是没人看到,而是在含混结论里被稀释了。

二十、小结

版本准入的本质,是让发布决策有证据、有边界、有止损能力。稳定性指标告诉我们版本当前表现,阻断项告诉我们哪些风险不能妥协,灰度建议告诉我们风险放大后如何观察和回滚。

一份好的准入结论,不一定总是“通过”。它可以是不通过,也可以是带条件进入下一阶段。但无论哪种结论,都要写清楚依据、条件和动作。这样版本推进才不会依赖临场争论,而是依赖团队共同认可的质量规则。