应用编译优化
首先,我们来明确一下 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 的所有代码。
这种方式的好处是:
- 提升性能:应用启动和常用操作会很快,因为最关键的代码已经是机器码了。
- 节省空间:比完全 AOT 编译(编译所有代码)节省磁盘空间。
- 加快安装速度:安装时不需要进行重量级的完整编译。
预编译成功的应用应该显示什么状态?
这个问题的答案取决于你对“预编译成功”的定义。在现代 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 状态。