启动监控三板斧:DisplayManager、adb 与 Play Console

做启动优化,最怕的就是“凭感觉”。你改了几行代码,觉得快了,但到底快了多少?哪个阶段拖了后腿?没有数据支撑,一切优化都是盲人摸象。

这一章,我带你熟悉三套最常用的启动监控工具。它们各有侧重,结合起来基本能覆盖从开发到线上全链路。我自己做项目时,这三样东西几乎天天都要摸一遍——嗯,就像医生手里的听诊器、血压计和CT机。

Android 启动监控工具的三大法宝 启动监控工具集 ① DisplayManager 启动信息 ② adb shell am start -W ③ Google Play Console 报告 Activity / App 启动时间戳 Display 帧渲染耗时 冷启动 vs 温启动分类 TotalTime / WaitTime ActivityManager 日志 命令行脚本化批量采样 Android Vitals 启动延时 设备型号 / 系统版本分布 对比基准版本趋势 开发阶段用 DisplayManager + adb,线上用 Play Console,三者互补,不漏死角

1. DisplayManager 启动信息:官方最精确的系统级指标

先聊 DisplayManager。说实话,很多人不知道这个 API。它藏在 android.view.Display 里,专门记录系统第一次绘制到屏幕的时间点。

怎么用? 在 Activity 的 onCreate 或 onResume 里加上几行代码:

// 获取 Display 对象
Display display = getWindowManager().getDefaultDisplay();
// 注册启动时间监听(API 24+)
display.getMetrics(new DisplayMetrics());

// 更直接的方式:使用 reportFullyDrawn()
// 在关键内容渲染完成后调用
Activity.reportFullyDrawn();

我的一点经验:reportFullyDrawn() 这个方法非常实用。它告诉系统“我的核心界面已经完整展示了”。系统会在 Logcat 里打出一条包含启动耗时的日志,格式类似:

Displayed com.example.app/.MainActivity: +1s234ms

你可以把它作为冷启动耗时的一个基准。我在多个项目中用这个指标和 adb 命令交叉验证,两者基本吻合。

DisplayManager 信息的主要价值:

  • 最接近用户感知:它记录的是屏幕真正亮起的时间,不是代码逻辑跑完的时间。
  • 区分冷/温/热启动:系统日志会自动标注。
  • 零性能开销:纯系统级统计,不需要额外埋点。

注意:reportFullyDrawn() 只在 Android 4.4(API 19)以上有效。另外,如果你在 Activity 的 onCreate 里做了大量同步耗时任务,DisplayManager 不会等你做完才打时间戳,它只管第一帧的显示。所以——不要让它背锅,你需要结合其他工具看内部耗时。

2. adb shell am start -W:命令行硬核诊断

这是我最常用的调试手段。没有之一。你想想看,在开发机上敲一条命令,一秒后就能看到启动耗时,多爽。

基本命令:

adb shell am start -W -n com.example.app/.MainActivity

输出结果大致如下:

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.app/.MainActivity }
Status: ok
LaunchState: COLD
Activity: com.example.app/.MainActivity
TotalTime: 1234
WaitTime: 1245
Complete

关键字段解释:

字段 含义 个人使用心得
TotalTime 从启动到 Activity 完成 onResume() 的耗时 我最关注的指标,单位毫秒
WaitTime 包含系统调度、AMS 处理等时间 通常比 TotalTime 大一些,但不建议用做优化目标
LaunchState COLD / WARM / HOT 必须关注。同一台设备冷启动 1.5s,热启动可能只有 200ms

批量测试脚本:我自己写过一个自动脚本,每次 CI 构建后,自动在 5 台真机上跑 10 次冷启动,取中位数和 P90。脚本大致逻辑:

# 先强杀进程确保冷启动
adb shell am force-stop com.example.app
sleep 2
adb shell am start -W -n com.example.app/.MainActivity 2>&1 | grep TotalTime

然后把结果写到 CSV 文件里,方便看趋势。这种方法比 Android Studio 的 Profiler 更轻量,适合集成到自动化流程。

我曾经踩过的坑:直接拿 am start -W 的结果和线上数据对比,发现永远对不上。后来搞清楚了——adb 测试时设备是空闲的,而线上用户手机后台跑着微信、抖音,CPU 负载不同。所以 adb 数值用于相对比较(优化前 vs 优化后),不要当成值。

3. Google Play Console 启动报告:线上的真实世界

开发环境再完美,也模拟不出线上用户的百机千态。Google Play Console 里的 Android Vitals 面板,才是真正反映用户体感的起点。

哪里看?

  1. 登录 Google Play Console → 选择应用 → Android Vitals → 启动时间。
  2. 会看到 “启动延时(冷启动)”、“启动延时(温启动)”、“启动延时(热启动)” 三个维度。
  3. 数据按设备型号、Android 版本、内存大小等维度聚合展示。

重点关注两个指标:

  • P50 和 P95:P50 代表一半用户的体验,P95 代表最差那 5% 用户的体验。如果 P95 远高于 P50,说明存在某些设备或机型上启动异常慢。
  • “差”的占比:Google 定义超过 5 秒的冷启动为“差”。如果你的应用这个比例超过 2%,建议马上排查。

重要提示:Play Console 的启动数据是基于 reportFullyDrawn() 上报的。如果你的应用没有调用 reportFullyDrawn(),那这个面板就是空的!我见过不少团队把代码都优化完了,才发现数据没上报,白忙活一场。

另外,Play Console 还有一些隐藏功能:

  • 按地区筛选:不同国家的网络条件会影响启动时下载的资源。
  • 查看启动崩溃关联:启动时间过长的 App 往往也伴随 ANR 率高。
  • 设置告警阈值:当 P95 启动时间超过某个值(比如 3 秒),自动发邮件提醒。

三者如何配合使用?

我个人习惯的开发流程是这样:

  • 日常开发:用 adb shell am start -W 快速验证每次改动的效果。改一点测一点,避免积重难返。
  • 回归测试:结合 DisplayManager 日志和自动化脚本,在 10 台以上设备跑批量测试,记录 TotalTime 和 Displayed 时间。
  • 线上监控:登陆 Play Console 看趋势。如果发现某个版本启动时间突然恶化,立刻定位优化。

嗯,这一套组合拳下来,基本不会有遗漏。记住一个原则:不经过数据验证的优化,都是自我感动。


核心总结:

  • reportFullyDrawn() + DisplayManager 日志 = 系统级基准
  • adb shell am start -W = 强插桩,适合本地快速验证
  • Play Console Android Vitals = 线上用户真实体验数据
  • 三者数据互为补充,不要只看一个维度下结论