2. 热启动与温启动耗时对比测量

热启动与温启动耗时对比测量 学习卡片

为什么热启动、温启动、冷启动的耗时不能直接比较

冷启动从进程不存在开始,包含进程创建、Application 初始化、Activity 创建与首帧渲染;热启动时进程与 Activity 对象都还在,系统只需把已有任务栈重新切到前台;温启动介于两者之间——进程仍存活,但 Activity 已被销毁,需要重新执行 Activity 创建与首帧渲染。三者起点不同,因此对比时必须先固定“起点定义”,否则测出来的差值没有意义。

三种启动场景的进程 / Activity 状态与耗时构成 冷启动 温启动 热启动 进程:不存在 → 新建 Activity:不存在 → 新建 进程创建 + Application 初始化 Activity 创建 首帧渲染 耗时最长(基线) 进程:存活(已初始化) Activity:已销毁 → 重建 进程创建 + Application 初始化 Activity 创建 首帧渲染 省去进程与 Application 阶段 进程:存活(已初始化) Activity:存活 → 直接恢复 进程创建 + Application 初始化 Activity 创建 首帧渲染 仅剩窗口恢复与首帧 跳过 跳过 跳过 耗时短 耗时长 对比前提:三者的“起点”必须分别定义为 进程不存在 / 进程存活但 Activity 销毁 / 进程与 Activity 均存活。 差值来源:温启动相对冷启动省去进程创建与 Application 初始化;热启动再省去 Activity 创建。

构造三种场景的操作要点

测量前先确认设备处于稳定状态,避免后台任务、系统更新或低电量模式干扰。以下操作在真机或模拟器上均可执行,关键是每次测量前把应用恢复到对应状态。

  • 冷启动:在系统设置中强制停止应用,或执行 adb shell am force-stop 包名,确认进程已不存在后再点击图标启动。
  • 温启动:先正常启动应用,按返回键退出到桌面(Activity 被销毁但进程保留),再重新点击图标。可用 adb shell dumpsys activity processes | grep 包名 确认进程仍在。
  • 热启动:启动应用后按 Home 键回到桌面(Activity 进入后台但未销毁),再点击图标恢复。此时进程与 Activity 对象都存活。
判断进程是否存活,最直接的方式是查看 adb shell ps | grep 包名 是否有输出;判断 Activity 是否存活,可观察 adb shell dumpsys activity activities 中该 Activity 是否仍处于 RESUMED 或 PAUSED 状态。

用 am start 的 -W 参数采集耗时

Android 提供了 am start -W 命令,可以输出本次启动的 TotalTime、WaitTime 等指标。它测量的是从 am 命令发出到 Activity 首帧显示的时间,适合快速对比三种场景。示例命令:

# 冷启动:先强制停止,再启动
adb shell am force-stop com.example.app
adb shell am start -W -n com.example.app/.MainActivity

# 温启动:启动后按返回键退出,再启动
adb shell input keyevent KEYCODE_BACK
adb shell am start -W -n com.example.app/.MainActivity

# 热启动:启动后按 Home 键,再启动
adb shell input keyevent KEYCODE_HOME
adb shell am start -W -n com.example.app/.MainActivity

每次执行后记录输出中的 TotalTime。建议每种场景连续测量 5 次,去掉第一次(可能受系统缓存影响),取后 4 次的平均值作为该场景的耗时。示例记录如下(数值为教学示例,非真实设备实测):

场景第1次第2次第3次第4次第5次平均(后4次)
冷启动820 ms790 ms805 ms795 ms800 ms797.5 ms
温启动410 ms395 ms400 ms390 ms405 ms397.5 ms
热启动120 ms110 ms115 ms108 ms112 ms111.25 ms

结果判读与影响边界

从示例数据可以看到:温启动比冷启动快约 400 ms,这部分差值主要来自省去的进程创建与 Application 初始化;热启动又比温启动快约 286 ms,这部分来自省去的 Activity 创建与布局加载。这说明进程存活状态对启动耗时的影响集中在 Application 初始化阶段,而 Activity 是否存活则影响 Activity 创建与首帧渲染阶段。

需要特别注意:如果 Application 初始化本身很轻,冷启动与温启动的差距会缩小;如果 Activity 布局复杂,温启动与热启动的差距会拉大。因此不能脱离具体应用谈“热启动一定比温启动快多少”,而应把三种场景的耗时作为一组基线,后续优化时分别观察各阶段的变化。

用 am start -W 测量时,如果应用有启动页或广告页,TotalTime 可能只统计到第一个 Activity 显示,不代表用户真正看到主界面的时间。此时应结合 adb shell am start -W 的 ThisTime 与自定义埋点综合判断。

可复用的测量记录表

把每次测量的原始数据填入下表,便于后续对比优化效果。字段可根据实际需要增减。

日期设备/系统场景TotalTime 原始值(ms)后4次平均(ms)备注
示例Pixel 6 / Android 14冷启动820, 790, 805, 795, 800797.5首次测量前已 force-stop
示例Pixel 6 / Android 14温启动410, 395, 400, 390, 405397.5返回键退出后进程仍存活
示例Pixel 6 / Android 14热启动120, 110, 115, 108, 112111.25Home 键后 Activity 未销毁

完成记录后,用“冷启动平均 − 温启动平均”得到进程与 Application 初始化的代价,用“温启动平均 − 热启动平均”得到 Activity 创建与首帧渲染的代价。这两个差值就是后续优化时最值得关注的边界。