Android DEX 预优化 & 编译常用变量速查表
分全局编译变量 (命令行/全局配置)、模块级变量 (Android.mk / Android.bp)、常用组合命令 、场景选型四部分,适配传统 Make + Soong 双构建体系。
一、全局变量(make/m 命令行 / build 全局配置)
作用:本次编译所有模块统一生效,优先级:命令行 > 全局配置
| 变量 | 取值 | 说明 | 适用场景 |
|---|---|---|---|
WITH_DEXPREOPT |
true |
全局开启 DEX 预优化(dex2oat),编译阶段生成 .odex/.oat |
user 正式版本、量产固件,加快开机 |
false |
全局关闭预优化,只保留原始 dex,开机首次运行才做优化 | 调试、反复刷包、模块频繁修改,编译更快、镜像更小 | |
DONT_DEXPREOPT_PREBUILTS |
true |
不对预编译三方库/预装APK做预优化 | 调试第三方预编译包、缩减镜像体积 |
false |
所有预装包统一预优化 | 量产版本 | |
WITH_DEXPREOPT_BOOT_IMG_ONLY |
true |
仅对 boot 镜像内 jar/dex 做预优化,系统应用不优化 | 折中方案:开机提速 + 控制镜像大小 |
DISABLE_DEXPREOPT |
true |
强制全局禁用所有 dex 预优化(优先级高于 WITH_DEXPREOPT) | 快速编译、排查 dex2oat 报错 |
补充默认规则
lunch xxx-user:默认WITH_DEXPREOPT=truelunch xxx-userdebug / eng:默认WITH_DEXPREOPT=false- 命令行传参可强制覆盖默认值
二、Android.mk 模块级变量(传统 Make 模块)
仅对当前单个模块生效,优先级高于全局变量
| 变量 | 取值 | 说明 |
|---|---|---|
LOCAL_DEX_PREOPT |
true |
当前模块单独开启预优化 |
false |
当前模块关闭预优化 | |
LOCAL_DEX_PREOPT_JAR |
true/false |
单独控制 JAR 包的预优化 |
LOCAL_NO_DEX |
true |
模块不生成 DEX,自然也不会走预优化 |
示例片段:
makefile
# 该模块单独开启预优化,不受全局开关影响
LOCAL_DEX_PREOPT := true
# 该模块强制关闭预优化
# LOCAL_DEX_PREOPT := false
三、Android.bp 模块级配置(Soong 新构建,Android 7.0+)
对应 mk 语法,Soong 体系专用,作用范围同样为单个模块
1. 普通 APK / App 模块
json
android_app {
name: "SettingsProvider",
// 开启预优化
dex_preopt: {
enabled: true,
},
// 关闭预优化
// dex_preopt: {
// enabled: false,
// },
}
2. Java Library (jar) 模块
json
java_library {
name: "xxx-lib",
dex_preopt: {
enabled: true,
},
}
全局 Soong 兜底配置
device/xxx/xxx/soong_config.mk 中可全局默认开关:
makefile
SOONG_CONFIG_android_dex_preopt := true
四、高频实用编译命令(结合多线程 + 优化开关)
统一使用 m(推荐,任意目录执行),make 需在源码根目录
1. 标准用法(规范顺序:变量 → 线程 → 目标)
bash
# 全局开启预优化,编译 SettingsProvider,CPU 满线程编译
m WITH_DEXPREOPT=true -j$(nproc) SettingsProvider
# 全局关闭预优化(调试首选,编译更快)
m WITH_DEXPREOPT=false -j$(nproc) SettingsProvider
# 强制全局禁用所有预优化(最高优先级)
m DISABLE_DEXPREOPT=true -j$(nproc) SettingsProvider
2. 仅优化 boot 镜像,其余不优化
bash
m WITH_DEXPREOPT_BOOT_IMG_ONLY=true -j$(nproc) SettingsProvider
3. 编译整个系统 + 全局预优化(量产镜像)
bash
m WITH_DEXPREOPT=true -j$(nproc)
4. 跳过预优化 + 跳过预编译包优化(极致提速调试)
bash
m WITH_DEXPREOPT=false DONT_DEXPREOPT_PREBUILTS=true -j$(nproc)
五、场景选型 & 避坑指南
1. 该开还是关?
- 量产/正式固件 :开
WITH_DEXPREOPT=true→ 开机快、运行性能好,代价是镜像体积变大、编译变慢 - 日常调试/迭代模块 :关
WITH_DEXPREOPT=false→ 编译速度大幅提升,刷包测试更高效 - 只改单个应用 :优先用模块级开关(LOCAL_DEX_PREOPT / dex_preopt),不要改全局
2. 常见问题
- 开启预优化后编译报错 dex2oat
临时加DISABLE_DEXPREOPT=true跳过优化,先排查代码问题 - system.img 空间不足
关闭全局预优化,或仅开启 boot 镜像优化 - 改了模块代码,生效异常
预优化会缓存 odex 文件,建议编译前先清缓存:make clean-SettingsProvider
3. 优先级总结(从高到低)
模块级配置(Android.mk/bp) > 命令行全局变量 > 系统默认配置(lunch 类型)