应用启动时间

定义启动机制

应用正常启动是有三种启动模式,每种状态都会影响应用向用户显示所需的时间:

  • 冷启动
  • 温启动
  • 热启动

在冷启动中,应用从头开始启动。在另外两种状态中,系统需要将后台运行的应用带入前台。

建议您始终在假定冷启动的基础上进行优化,这样做也可以提升温启动和热启动的性能。也就是说冷启动优化好了,其他两种启动方式也会显著提升。

1. 冷启动

1.1 定义

冷启动是指应用从头开始启动:系统进程在冷启动后才创建应用进程。发生冷启动的情况包括应用自设备启动后或系统终止应用后首次启动。这种启动给最大限度地减少启动时间带来了最大的挑战,因为系统和应用要做的工作比在另外两种启动状态中更多。

在冷启动开始时候,系统有三个任务,他们是:

  1. 加载并启动应用
  2. 在启动后立即显示应用的空白启动窗口
  3. 创建应用进程

系统一创建应用进程,应用进程就负责后续阶段:

  1. 创建应用对象。
  2. 启动主线程。
  3. 创建 Launch Main Activity。
  4. 扩充视图。
  5. 布局屏幕。
  6. 执行初始绘制。

一旦应用进程完成第一次绘制,系统进程就会换掉当前显示的后台窗口,替换为主 Activity。此时,用户可以开始使用应用。

图 1 显示系统进程和应用进程之间如何交接工作

img

在创建应用和创建 Activity 的过程中可能会出现性能问题。

1.2 优化方向

1.2.1 应用创建

当应用启动时,空白启动窗口将保留在屏幕上,直到系统首次完成应用绘制。完成后,系统进程会换掉应用的启动窗口,允许用户开始与应用互动。

如果您在自己的应用中使 Application.onCreate() 过载,系统将在应用对象上调用 onCreate() 方法。之后,应用生成主线程(也称为界面线程),并用其执行创建主 Activity 的任务。

1.2.2 首个页面创建

在应用进程创建后,就会启动首个 Activity ,Activity 将执行以下操作:

  1. 初始化值。
  2. 调用构造函数。

根据 Activity 的当前生命周期状态,相应地调用回调方法,如 Activity.onCreate()。

通常 onCreate() 方法对加载时间的影响最大,因为它执行工作的开销最高:加载和膨胀视图,以及初始化运行 Activity 所需的对象。

1.2 冷启动时间收集

1.2.1 Logcat 自动打印

从 Android 4.4 之后的版本,Logcat 会自动帮打印出应用的启动时间。这个时间就是从应用启动(创建进程)开始计算,到完成视图的第一次绘制(即 Activity )为止。

以下以媒体为例子,启动统计耗时

先杀死老的进程:

1
adb shell am force-stop com.iflytek.autofly.mediax
1
2022-01-05 15:16:17.644 1006-1037/system_process I/ActivityManager: Displayed com.iflytek.autofly.mediax/.MainActivity: +1s859ms

1.2.2 adb shell 测量

1
adb [-d|-e|-s <serialNumber>] shell am start -S -W     com.iflytek.autofly.mediax/.MainActivity     -c android.intent.category.LAUNCHER     -a android.intent.action.MAIN

Displayed 的数据就会在 控制台 显示 示例如下

1
2
3
4
5
6
7
8
9
adb  shell am start -S -W     com.iflytek.autofly.mediax/.MainActivity     -c android.intent.category.LAUNCHER     -a android.intent.action.MAIN
Stopping: com.iflytek.autofly.mediax
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.iflytek.autofly.mediax/.MainActivity }
Status: ok
Activity: com.iflytek.autofly.mediax/.MainActivity
ThisTime: 1809
TotalTime: 1809
WaitTime: 1835
Complete

2 热启动

2.1 定义

应用的热启动比冷启动简单得多,开销也更低。在热启动中,系统的所有工作就是将您的 Activity 带到前台。只要应用的所有 Activity 仍驻留在内存中,应用就不必重复执行对象初始化、布局膨胀和呈现。

2.2 热启动时间收集

执行 adb 命令,不是所有的 activity 都可以执行这个方法。

1
adb shell am start -W com.iflytek.autofly.mediax/.MainActivity

3 温启动

温启动包含了在冷启动期间发生的部分操作;同时,它的开销要比热启动高。有许多潜在状态可视为温启动。例如:

  • 用户在退出应用后又重新启动应用。进程可能已继续运行,但应用必须通过调用 onCreate() 从头开始重新创建 Activity。

  • 系统将您的应用从内存中逐出,然后用户又重新启动它。进程和 Activity 需要重启,但传递到 onCreate() 的已保存的实例 state bundle 对于完成此任务有一定助益。

如果优化好了冷启动就不需要额外优化热启动

4 启动时间统计

我们统计一些的车机APP的冷启动时间:

测试车机 CPU 是 8155 内存 8G

应用 冷启动耗时 热启动耗时
媒体 1s859ms 148ms
设置 360ms 169ms
语音助理 907ms 103ms
爱奇艺 1s200ms 169ms
火山车娱 563ms 344ms
车服务 851ms 244ms
应用商店 882ms 272ms
唱吧 1s241ms 351ms
bilibili 1s267ms 341ms
场景引擎 905ms 151ms

5 启动时间指标

5.1 软件绿色联盟标准 img

参考:软件绿色联盟性能标准 冷启动时间 链接

img img

参考:软件绿色联盟性能标准 热启动时间 链接

5.2 星河标准

5.2.1 冷启动标准

用例描述 测量点击应用图标到打开应用的冷启动响应时间(毫秒)
预置条件 被测应用在测试之前从未创建过进程b. 测量从点击图标到界面全部显示的时间
测试方法 起点:点击应用图标 终点:应用主界面显示完成
判定标准 各类应用(不含游戏类、影音娱乐)的冷启动时间应 ≤ 800毫秒 游戏类应用冷启动时间 ≤ 1200毫秒 影音娱乐类应用冷启动时间 ≤ 1500毫秒 界面加载过程中白屏/黑屏停留时间 ≤ 100毫秒

5.2.2 热启动时间

用例描述 测量点击应用图标到打开应用的热启动响应时间(毫秒))
预置条件 被测应用之前已经被打开过,无关闭应用行为,测试时被 重新切换到前台
测试方法 起点:点击应用图标 终点:应用主界面显示完成
判定标准 各类应用(不含游戏类、影音娱乐)的热启动时间应 ≤ 150毫秒 游戏类应用热启动时间 ≤ 180毫秒 影音娱乐类应用热启动时间 ≤ 180毫秒 界面加载过程中白屏/黑屏停留时间 ≤ 100毫秒

6 诊断识别问题

6.1 启动白屏/黑屏

6.1.1 诊断原因

通常可以用于诊断此问题的方法是观察用户启动应用时,应用的响应是否很慢:在这种情况下,屏幕看起来会像是卡住了,或停止了对输入做出响应。

6.2 应用初始化耗时太久

6.3 Activity启动耗时太久

参考文献:

adb 常用命令

  • 获取顶部的activity和APP包名
1
adb shell dumpsys window | grep mCurrentFocus
  • 热启动耗时统计
1
adb shell am start -W   com.iflytek.autofly.mediax/com.iflytek.autofly.mediax.MainActivity
  • 冷启动耗时
1
adb  shell am start -S -W     com.gxatek.cockpit.carservice/com.gxatek.cockpit.carservice.base.MainActivity     -c android.intent.category.LAUNCHER     -a android.intent.action.MAIN