应用编译优化

首先,我们来明确一下 speed-profile 这个状态的含义。

在现代 Android 版本中(Android 7.0 Nougat 及以后),应用代码的编译采用了混合模式,即 JIT (Just-In-Time)AOT (Ahead-of-Time) 相结合的方式。

  • JIT (Just-In-Time): 应用在运行时,动态地将用得最频繁的 Java/Kotlin 字节码编译成机器码。
  • AOT (Ahead-of-Time): 在应用的安装期间或者在设备空闲时,提前将部分或全部代码编译成机器码。

speed-profile 正是这个混合模式中的一个关键状态。

speed-profile 状态的含义是:

应用已经通过 AOT 编译,但编译的依据是一个 “配置文件” (Profile)。这个配置文件记录了应用在前台运行时最常用、最热门的代码路径(Hot Paths)。系统只会预先编译这些热门路径,而不是编译整个 App 的所有代码。

这种方式的好处是:

  1. 提升性能:应用启动和常用操作会很快,因为最关键的代码已经是机器码了。
  2. 节省空间:比完全 AOT 编译(编译所有代码)节省磁盘空间。
  3. 加快安装速度:安装时不需要进行重量级的完整编译。

预编译成功的应用应该显示什么状态?

这个问题的答案取决于你对“预编译成功”的定义。在现代 Android 系统中,有不同级别的预编译状态。

1. 理想的、最常见的预编译状态:speed-profile

对于绝大多数应用来说,经过一段时间的使用和后台优化后,最理想和最常见的状态就是 speed-profile。这表明系统已经成功地收集了使用信息,并基于这些信息对热点代码进行了 AOT 编译。因此,当应用显示 speed-profile 时,就可以认为它已经处于一个良好的预编译状态。

2. 完全 AOT 编译的状态:speed

如果你希望整个应用被完全 AOT 编译,而不是仅仅基于 Profile,那么最终的状态应该是 speed

  • speed 状态:表示应用的 所有 代码都已经被 AOT 编译成了机器码。这是最彻底的预编译,理论上能提供最佳的性能(避免了任何运行时的 JIT 编译),但会占用更多的存储空间,并且在安装时或后台优化时需要更长的时间。

如何手动强制应用达到 speed 状态?

你可以通过 adb 命令手动触发对整个应用的完整 AOT 编译:

# -m speed 表示使用 'speed' 编译配置,即完全 AOT 编译
# -f 表示强制重新编译
adb shell cmd package compile -m speed -f <your.app.package.name>

执行成功后,再次检查编译状态,就应该能看到它从 speed-profile 或其他状态变成了 speed


如何检查应用的编译状态?

你可以使用以下 adb 命令来查看设备上应用的当前编译状态:

adb shell dumpsys package <your.app.package.name> | grep -A 1 "status="

输出解读:

  • speed-profile: 基于配置文件进行了部分 AOT 编译。这是最常见和推荐的优化状态。
  • speed: 整个应用都被 AOT 编译。
  • verify: 纯解释执行模式,没有进行任何 AOT 编译。通常是应用刚安装后、还没来得及优化时的状态,性能最差。
  • quicken: 一种较旧的编译模式,现在已不常见。
  • (空) 或 run-from-apk: 通常意味着代码直接从 APK 中解释执行,也是未优化的状态。

总结

编译状态含义性能表现备注
verify仅验证字节码,纯解释执行较差应用刚安装或清除数据后的初始状态
speed-profile基于使用情况配置文件,对热点代码进行 AOT 编译良好现代 Android 系统中最常见、最理想的自动优化状态
speed对应用的全部代码进行 AOT 编译最佳占用空间最大,可通过手动命令强制触发

所以,回答你的问题:一个预编译成功的应用,在常规的自动优化流程下,应该显示 speed-profile 状态。 如果你追求极致的性能并手动干预,那么它会显示 speed 状态。