Android
相关缩写
- AGP(Android Gradle Plugin):Google 官方为 Android 开发打造的 Gradle 插件**,核心作用是将 Gradle 构建系统与 Android 开发流程深度整合,让开发者能通过简洁的配置完成 Android 项目的编译、打包、优化、签名等全流程构建工作。
- 压缩(Shrinking)
- 优化(Optimization)
- 混淆(Obfuscation)
- 脱糖(Desugaring)
- ProGuard(混淆 / 压缩)
- AAPT2(Android Asset Packaging Tool 2):编译资源文件(布局、字符串、图片等),生成 R 类
- APT(Annotation Processing Tool):Java APT 是 编译期注解处理工具,核心作用是在代码编译阶段扫描并处理自定义注解,生成新的 Java 代码,而非运行时通过反射处理,能有效提升程序性能,是 Android 主流框架(如 ARouter、Dagger2、ButterKnife)的核心实现技术。
- Build Type(Debug/Release)、Product Flavor(渠道包)、Build Variant(变体组合)
- APK(Android Package):Android 应用安装包,是 Android 系统中应用的分发和安装格式,相当于 Windows 系统的.exe文件、iOS 系统的.ipa文件。
- AAB(Android App Bundle):新型 Android 应用发布格式,和你之前了解的 APK 是互补且升级的关系。
- ART(Android Runtime):Android 运行时。
- PGO(Profile Guided Optimization):提前编译,不是独立编译模式,而是 “编译优化策略”;先运行应用收集性能数据(热点方法、分支走向),再基于数据做针对性编译优化(如方法内联、常量折叠);记录用户常用功能,仅对高频代码做 AOT 编译,减少安装时间和存储占用。
- OTA(Over-the-Air):空中下载技术,是 Android 系统 / 应用的 “无线升级方式”(比如手机在线更系统、更新APP)
- Dex(Dalvik Executable)
- ABI(Application Binary Interface,应用二进制接口)
- APM(Application Performance Management):应用性能管理。它是一套监控、分析、优化应用全生命周期性能与稳定性的工具 / 方案体系,核心目标是提前发现性能瓶颈、定位线上故障、提升用户体验。
- BoM(Bill of Materials):物料清单(也译作 “依赖清单”)
- Alpha 内部早期测试版,功能未完整,Bug 多 极低 开发团队内部验证
- Beta 公开测试版,功能完整,仍有部分 Bug 中等 面向开发者 / 用户收集反馈
- RC 版(Release Candidate):发布候选版本」,是软件 / SDK / 系统发布前的关键测试版本
- GA/Gold Master(General Availability):正式版 最终发布版,经过充分验证,通用可用版,即正式版
- MR(Maintenance Release):维护更新版(正式版发布后的小版本修复);
- SNAPSHOT:快照版(开发中的实时构建版,稳定性最低)。
- ODM(Original Design Manufacturer),中文译为原始设计制造商,是一种常见的电子设备代工模式,核心是厂商自主完成产品的设计、研发,再按客户需求贴牌生产。
- dpi(Dots Per Inch):每英寸点数,也可称为像素密度,即屏幕对角线像素值÷英寸值
Android 虚拟机
Android 虚拟机是应用的 “执行核心”:把 Dex 字节码翻译成硬件能跑的机器码,同时管内存、调线程、做隔离、处理异常,最终让 Java/Kotlin 写的应用能高效、安全地在手机上运行。
- Dalvik 是 Android 早期的轻量级虚拟机,因 JIT 编译的性能缺陷被淘汰;
- ART 是当前 Android 的核心运行时,通过 AOT+JIT 混合编译实现 “高性能 + 低功耗”,是所有现代 Android 设备的应用运行基础;
- 对开发者而言,只需关注代码的 DEX 兼容性(如反射、多 DEX),无需直接操作虚拟机,AGP 编译生成的 DEX 会自动适配 ART 运行时。
Dalvik/ART 是什么?
Dalvik 和 ART 是 Android 系统中负责执行 DEX 字节码的虚拟机(VM),是 Android 应用运行的核心底层组件 —— 前者是 Android 早期的默认虚拟机,后者是 Google 为解决 Dalvik 性能问题推出的新一代替代方案,两者均为 Android 专属设计,适配移动设备的内存、性能特性。
简单来说:Dalvik/ART 是 Android 应用的 “运行时引擎”,相当于 Java 程序的 JVM、iOS 程序的 Objective-C/Swift 运行时,核心作用是解析并执行 APK 中的 DEX 字节码,让应用代码能在 Android 设备上跑起来。
为什么 Android 不用 JVM?
Java 程序的 JVM 执行的是 .class 字节码,且依赖大内存、高算力,不适合移动设备;而 Android 先通过 D8/R8 将 .class 转为 .dex 字节码(更紧凑、省内存),再由 Dalvik/ART 执行 —— 这是 Android 专为移动场景做的核心优化:
- DEX 字节码:单个文件可包含多个类,结构更紧凑,内存占用仅为 .class 的 1/5;
- 虚拟机适配:Dalvik/ART 针对移动设备的低内存、低功耗做了深度优化。
ART 虚拟机(当前主流)
1. 核心定位
ART(Android Runtime)中文译为 Android 运行时,是 Google 在 Android 4.4 中引入(与 Dalvik 并存)、Android 5.0(Lollipop)后开始成为系统默认的虚拟机,通过 AOT+JIT + 解释器的混合编译模式,实现了更优的运行性能和更低的功耗,完全替代 Dalvik 的新一代虚拟机,核心目标是解决 Dalvik 的性能和功耗问题。
- 替代 Dalvik 的 Android 新一代应用运行时,Android 5.0 及以上系统默认虚拟机。
- 负责解析并执行 APK 中的 DEX 字节码,是应用运行的底层核心引擎。
2. 核心特性(对比 Dalvik)
| 特性 | ART | Dalvik |
|---|---|---|
| 编译方式 | AOT + JIT + 解释器 | 仅 JIT + 解释器 |
| 运行性能 | 提升 2~3 倍 | 低(运行时编译) |
| 启动速度 | 首次启动稍慢(预编译) | 快(无预编译) |
| 功耗 | 低(减少运行时计算) | 高(JIT 编译耗资源) |
| 兼容性 | 更好(统一优化) | 碎片化严重 |
3. 核心编译模式(混合编译)
ART 采用 “分层编译” 策略,兼顾性能和灵活性(Android 7.0 后优化为混合模式):
- AOT 编译(预编译):应用安装 / 更新时,提前将 DEX 字节码编译为机器码(存储在设备本地),运行时直接执行,无需实时编译;
- JIT 编译(即时编译):对低频代码仍用解释器,对热点代码实时编译并缓存,补充 AOT 的不足;
- Profile Guided Optimization(PGO):记录用户常用功能,仅对高频代码做 AOT 编译,减少安装时间和存储占用。
4. 核心优势
- 性能提升:AOT 预编译让应用运行更流畅,尤其是高频操作(如滑动、点击);
- 功耗降低:功耗显著降低,减少运行时的 CPU 计算,延长手机续航;
- 稳定性高:稳定性更高,预编译阶段可提前发现部分代码错误,减少运行时崩溃;
- 扩展能力:支持 64 位架构、硬件加速、垃圾回收(GC)优化等扩展能力。
Dalvik 虚拟机(已淘汰)
1. 核心定位
Dalvik 是 Android 1.0 ~ Android 4.4(KitKat)的默认虚拟机,由 Google 专门为 Android 设计,命名源于冰岛一个渔村。
2. 核心特性(优缺点)
| 优点 | 缺点 |
|---|---|
| 轻量级:适配低内存手机 | 性能差:采用 JIT 编译 |
| 启动快:无需预编译 | 耗电高:运行时编译耗资源 |
| 多进程:每个应用独立 Dalvik 进程,隔离性好 | 碎片化:不同设备优化不一致 |
3. 关键机制:JIT 编译(即时编译)
Dalvik 执行 DEX 字节码时,不会提前编译为机器码,而是:
- 运行时先通过 “解释器” 逐行解析 DEX 字节码;
- 对高频执行的代码(热点代码),临时编译为机器码并缓存;
- 应用退出后,缓存的机器码被清空,下次启动需重新编译。
这种方式启动快,但运行中编译会导致卡顿、耗电,是 Dalvik 被替换的核心原因。
Dalvik vs ART 核心差异总结
| 维度 | Dalvik | ART |
|---|---|---|
| 核心编译方式 | JIT(运行时编译) | AOT+JIT + 解释器(预编译 + 即时编译) |
| 性能 | 低(卡顿、耗电) | 高(流畅、低功耗) |
| 安装 / 更新 | 快(无预编译) | 稍慢(需预编译,Android 7.0 后优化) |
| 存储占用 | 小(无预编译产物) | 稍大(存储机器码) |
| 兼容性 | 差(碎片化) | 好(统一标准) |
| 适用版本 | Android 1.0 ~ 4.4 | Android 5.0 ~ 至今 |
开发者需要关注的点
- 无需手动适配:Dalvik/ART 是系统底层组件,开发者写的 Java/Kotlin 代码编译为 DEX 后,会自动适配当前系统的虚拟机,无需修改代码;
- APK 兼容性:针对 ART 编译的 APK 可向下兼容(Android 5.0+),无需区分 Dalvik/ART 版本;
- 性能优化:
- 避免频繁创建对象(减少 ART 的 GC 压力);
- 减少反射调用(ART 对反射的优化不如直接调用);
- 利用 ART 的 AOT 特性:高频代码尽量封装为独立方法,便于预编译优化;
- 调试注意:Android Studio 的调试工具(如 Profiler)基于 ART 设计,可直观查看应用的编译、内存、CPU 使用情况。
DEX 编译器
- R8 在 Android 10+ 场景下,底层会调用 D9 完成 DEX 转换,再叠加压缩 / 混淆 / 深度优化
- Android Gradle Plugin (AGP) 3.4.0 开始,R8 成为默认的编译工具(可手动回退到 ProGuard/D8);AGP 7.0+ 后完全移除对 ProGuard 的默认支持,全面转向 R8
- Android Gradle Plugin (AGP) 3.0.0 中推出 D8 替代 dx,并从 AGP 3.1.0 开始将 D8 设为默认的 DEX 编译器
- Android Gradle Plugin (AGP) 1.0 ~ 3.0 为核心工具,AGP 3.1 后被 D8 替代,AGP 7.0 完全移除支持
R8 编译器
R8 是 Google 官方推出的 Android 字节码优化与编译工具,核心作用是将 Android 项目的 Java/Kotlin 字节码(.class/.jar)转换为优化后的 DEX 字节码(Android 运行时 Dalvik/ART 可执行的格式),同时集成了代码混淆、压缩、优化、去冗余等能力,是 Android 构建流程中替代传统 ProGuard/D8 的新一代工具。
核心价值是「更小的安装包体积 + 更快的运行性能 + 更高效的构建速度」,已成为 Android 构建的标准工具,开发者无需额外学习成本,仅需注意反射等场景的配置兼容即可。
简单来说:R8 = D8(DEX 编译器) + ProGuard(混淆 / 压缩) + 更深度的优化能力。
核心定位与背景
- 推出背景:传统 Android 构建中,D8 仅负责将 Java 字节码转 DEX,ProGuard 负责混淆 / 压缩,两者分离导致优化链路割裂;Google 为统一编译流程、提升优化效果和构建速度,推出 R8 整合并增强这些能力。
- 默认启用:从 Android Gradle Plugin (AGP) 3.4.0 开始,R8 成为默认的编译工具(可手动回退到 ProGuard/D8);AGP 7.0+ 后完全移除对 ProGuard 的默认支持,全面转向 R8。
核心功能
R8 的核心能力可总结为「压缩(Shrinking)、优化(Optimization)、混淆(Obfuscation)、脱糖(Desugaring)、DEX 转换」:
1. 代码压缩(Shrinking)
移除项目中未被使用的代码(死代码),包括:
- 应用自身的未使用类 / 方法 / 字段;
- 第三方库(如 AndroidX、OkHttp)中的冗余代码;
- 仅保留运行时真正需要的代码,大幅减小 APK/AAB 体积。
2. 代码优化(Optimization)
深度优化字节码,提升运行性能:
- 内联(Inlining):将小方法直接嵌入调用处,减少方法调用开销;
- 常量折叠:编译期计算常量表达式(如
int a = 1 + 2直接优化为a = 3); - 无用代码消除:移除空方法、未使用的变量;
- 控制流优化:简化 if/else、循环等逻辑,减少分支判断;
- 移除调试信息:清理无用的日志、调试符号。
3. 代码混淆(Obfuscation)
- 将类名、方法名、字段名替换为无意义的短名称(如
MainActivity→a,getUser()→b()); - 增加逆向工程难度,保护代码安全;
- 同时生成
mapping.txt文件,用于混淆后的崩溃日志还原。
4. 脱糖(Desugaring)
- 将 Java 8+ 的语法特性(如 Lambda、Stream、默认方法)转换为低版本 Android 兼容的字节码;
- 无需依赖额外的兼容库,保证高版本语法在低版本 Android 设备上运行。
5. DEX 转换
- 最终将优化后的字节码转换为 ART/Dalvik 可执行的 DEX 文件(.dex),支持多 DEX 拆分(应对 65536 方法数限制)。
R8 vs ProGuard/D8
| 特性 | R8 | ProGuard + D8 |
|---|---|---|
| 核心能力 | 一站式(压缩 + 优化 + 混淆 + DEX) | 拆分(D8 转 DEX,ProGuard 混淆) |
| 优化深度 | 更深度(跨方法 / 跨类优化) | 基础优化 |
| 构建速度 | 更快(统一流程,减少中间步骤) | 较慢(多工具衔接) |
| 兼容性 | 对 Android 生态更适配 | 通用 Java 混淆工具,适配性弱 |
| 配置方式 | 兼容 ProGuard 规则(proguard-rules.pro) | 仅 ProGuard 规则 |
使用方式
R8 无需手动安装,由 Android Gradle Plugin 内置,默认启用,核心配置方式:
保留 ProGuard 配置兼容:
传统的
proguard-rules.pro规则完全适用于 R8,例如:# 保留某个类不被混淆 -keep class com.example.MyClass { *; } # 保留注解 -keepattributes *Annotation*proguard-rules.pro:
在
gradle.properties中配置:# 启用 R8(默认) android.enableR8=true # 禁用 R8(回退到 ProGuard/D8) android.enableR8=false调试优化:
可通过
android.enableR8.fullMode=true开启全量优化(更严格的死代码移除),但需确保无反射导致的代码被误删。
关键注意事项
- 反射兼容:R8 会移除未被直接引用的类 / 方法,若通过反射调用(如
Class.forName("com.example.MyClass")),需在proguard-rules.pro中显式保留,否则会导致运行时崩溃。 - 日志移除:默认会移除
Log.d()/Log.i()等调试日志(可通过配置保留)。 - mapping 文件:构建后生成的
mapping.txt需妥善保存,用于崩溃日志的混淆还原(可上传到 Google Play Console)。 - 增量构建:R8 支持增量编译,大幅提升二次构建速度。
D9 编译器
D9 是 Google 针对现代 Android 设备的 ART 优化产物,开发者无需关注其底层调用逻辑,只需确保 AGP 版本 ≥ 4.0,项目会自动享受其带来的 Android 10+ 设备性能提升,是 “无感知优化” 的核心组件。
核心定位
- 全称:
D9 Dex Compiler,是 D8 的升级版专属 DEX 编译器; - 核心目标:针对 Android 10+(API 29+)的 ART 虚拟机做深度优化,生成更适配现代 ART 架构的 DEX 字节码;
- 归属:内置在 AGP 4.0+ 中,无需手动安装,由构建工具自动调度。
核心特性(对比 D8)
| 特性维度 | D9 | D8 |
|---|---|---|
| 核心优化方向 | 针对 Android 10+ ART 虚拟机(快速解释器、AOT 编译)做指令级优化 | 通用型 DEX 转换,适配全版本 Android |
| 运行性能 | 生成的 DEX 执行效率更高(ART 解释 / 编译速度提升) | 基础高效,无 ART 版本专属优化 |
| 兼容性 | 仅优先适配 Android 10+,向下兼容低版本(但无优化) | 全版本 Android 兼容(Android 4.0+) |
| 功能边界 | 包含 D8 所有核心能力(转换、脱糖、多 DEX 拆分) | 基础 DEX 转换 + 脱糖 + 基础优化 |
核心优势(为什么需要 D9)
- 适配 ART 新特性:针对 Android 10+ ART 的 “快速解释器” 优化指令布局,减少字节码解析耗时;
- 提升 AOT 编译效率:生成的 DEX 更适配 ART 的 AOT 预编译逻辑,应用安装 / 首次运行时的预编译速度更快;
- 降低运行时开销:优化 DEX 字节码的内存布局,减少 ART 执行时的内存占用和 CPU 调度成本;
- 完全兼容 D8 生态:无需修改代码 / 配置,继承 D8 的 Java 8+ 脱糖、多 DEX 拆分等能力。
使用方式(无手动操作,自动适配)
D9 无需开发者手动调用或配置,AGP 4.0+ 会根据以下规则自动选择:
当项目
targetSdkVersion ≥ 29(Android 10+):默认使用 D9 编译 DEX;当项目
targetSdkVersion < 29:自动回退到 D8 编译;强制指定(高级场景,不推荐):
// build.gradle (Module) 中强制启用 D9(仅 AGP 4.0+ 支持) android { dexOptions { useD9 true } }
关键注意事项
- 无独立命令行工具:D9 仅作为 AGP 内置组件运行,无像 dx/D8 那样的独立命令行调用方式;
- 无需额外适配:代码层面完全兼容 D8 生成的 DEX,仅系统底层执行逻辑优化;
- 优化效果感知:仅在 Android 10+ 设备上体现性能提升,低版本设备与 D8 无差异;
- 调试兼容:Android Studio 调试工具(Profiler、Debugger)完全兼容 D9 生成的 DEX,无调试障碍。
与 D8/R8 的关系
- D9 是 D8 的 “版本专属优化版”,而非独立工具链;
- R8 在 Android 10+ 场景下,底层会调用 D9 完成 DEX 转换,再叠加压缩 / 混淆 / 深度优化;
- 三者核心分工:
- D8:通用型 DEX 转换(全版本);
- D9:Android 10+ 专属 DEX 转换(优化版);
- R8:基于 D8/D9 做一站式编译优化(转换 + 压缩 + 混淆)。
D8 编译器
D8 是 Google 推出的 Android 专属 DEX 编译器(全称:D8 Dex Compiler),核心作用是将 Java/Kotlin 编译生成的字节码(.class 文件、.jar 包)转换为 Android 运行时(Dalvik/ART)可执行的 DEX 字节码(.dex 文件)—— 这是 Android 应用从 “通用 Java 字节码” 到 “Android 可执行代码” 的核心转换环节。
简单来说:D8 是 “Java 字节码 → DEX 字节码” 的专用转换器,是 Android 构建流程中 “编译链路” 的核心组件,也是 R8 的 “基础子集”(R8 整合了 D8 的 DEX 转换能力,并新增了混淆、压缩等功能)。
D8 解决了旧 dx 工具速度慢、兼容性差的问题,是 R8 的基础组件。对于普通开发者,D8 完全由 AGP 自动管理,无需手动操作;仅在需手动转换 DEX 或调试编译流程时,才需要关注其配置和使用方式。
D8 的核心定位与背景
1. 推出背景
在 D8 之前,Android 采用 dx 工具完成 .class → .dex 的转换,但 dx 存在明显缺陷:
- 构建速度慢,尤其是大型项目;
- 生成的 DEX 文件体积大;
- 对 Java 8+ 新特性(如 Lambda、方法引用)支持差;
- 优化能力弱。
Google 为解决这些问题,在 Android Gradle Plugin (AGP) 3.0.0 中推出 D8 替代 dx,并从 AGP 3.1.0 开始将 D8 设为默认的 DEX 编译器。
- 核心定位
D8 只聚焦 “字节码转 DEX” 这一个核心任务,不负责代码混淆、压缩、深度优化(这些是 R8 的能力),是 Android 构建流程中 “编译阶段” 的基础工具:
Java/Kotlin 代码 → javac/kotlinc → .class 字节码 → D8 → .dex 字节码 → 打包为 APK/AAB
D8 的核心功能
D8 仅围绕 “高效生成优化的 DEX 文件” 展开,核心能力包括:
1. 基础转换:.class → .dex
将标准 Java 字节码(包括 Kotlin 编译后的 .class)转换为 Android 专属的 DEX 格式,保证代码能在 Dalvik/ART 上运行。
2. Java 8+ 特性 “脱糖”(Desugaring)
自动将 Java 8+ 的语法特性(Lambda 表达式、方法引用、默认方法、Stream API 等)转换为低版本 Android 兼容的字节码,无需开发者手动引入兼容库(如 retrolambda),让低版本 Android 设备(如 API 21 以下)也能运行使用高版本 Java 语法的代码。
3. 性能与体积优化
相比旧的 dx 工具:
- 构建速度更快:增量编译支持 + 更高效的算法,大型项目构建速度提升 20%~50%;
- DEX 体积更小:优化字节码结构,减少冗余指令;
- 运行效率更高:生成的 DEX 代码更贴合 ART 虚拟机的执行特性。
4. 多 DEX 支持
自动处理 “65536 方法数限制” 问题,将超过限制的代码拆分为多个 .dex 文件(classes2.dex、classes3.dex 等),无需开发者手动配置多 DEX。
D8 与 R8 的关系(核心区分)
很多开发者会混淆两者,核心差异可总结为:
| 特性 | D8 | R8 |
|---|---|---|
| 核心定位 | 仅做 .class → .dex 转换 | 一站式优化(D8 功能 + 压缩 / 混淆 / 深度优化) |
| 核心能力 | 转换 + 基础脱糖 | 转换 + 脱糖 + 代码压缩 + 混淆 + 深度优化 |
| 适用场景 | 仅需纯 DEX 转换的场景 | 完整的 Android 构建优化 |
| 配置独立性 | 可单独使用 | 内置 D8,无法脱离 D8 核心能力 |
简单理解:R8 = D8 + ProGuard(混淆 / 压缩) + 深度优化,D8 是 R8 的 “基础模块”,R8 完全兼容 D8 的所有功能并做了扩展。
D8 的使用方式
D8 由 Android Gradle Plugin 内置,默认启用,无需手动安装,核心配置方式:
1. 启用 / 禁用 D8
在 gradle.properties 中配置(AGP 3.0+ 默认为 true):
# 启用 D8(默认)
android.enableD8=true
# 禁用 D8,回退到旧的 dx 工具
android.enableD8=false
2. 手动调用 D8(高级场景)
若需手动转换 .class/.jar 为 .dex,可通过 Android SDK 中的 d8 命令行工具(路径:$ANDROID_SDK/build-tools/<版本>/d8),例如:
# 将单个 .class 文件转为 .dex
d8 MyClass.class
# 将 jar 包转为 .dex
d8 my-library.jar
3. 兼容配置
D8 无需额外配置,但若需调整脱糖规则,可通过 AGP 的 compileOptions 指定 Java 版本:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
关键注意事项
- 仅负责转换,不做混淆 / 压缩:D8 不会移除未使用的代码,也不会混淆类名 / 方法名,若需这些能力,需使用 R8 或 ProGuard;
- 脱糖范围有限:仅处理 Java 8+ 的核心语法特性,部分高级特性(如
java.time包)仍需依赖core-library-desugaring库; - 与 R8 共存:启用 R8 时,D8 会被自动整合进 R8 的流程,无需单独配置;
- 调试支持:生成的 DEX 文件保留调试信息,可配合 Android Studio 调试。
dx 编译器(已废弃)
核心定位
- 全称:
dx tool,Android 早期官方唯一的 DEX 编译器; - 核心作用:将 Java/Kotlin 生成的 .class/.jar 字节码转换为 Dalvik/ART 可执行的 .dex 字节码;
- 生命周期:Android 1.0 ~ AGP 3.0 为核心工具,AGP 3.1 后被 D8 替代,AGP 7.0 完全移除支持
核心特性(优缺点)
| 优点 | 缺点 |
|---|---|
| 轻量、适配早期 Android 系统 | 构建速度慢(大型项目尤为明显) |
| 满足基础 DEX 转换需求 | DEX 文件体积大,无字节码优化 |
| - | 完全不支持 Java 8+ 特性(Lambda、Stream 等),需依赖 retrolambda 等第三方库兼容 |
| - | 无多 DEX 自动拆分能力,需手动处理 65536 方法数限制 |
典型使用方式(仅作历史参考)
# 基础命令:将 class 文件/目录转为 DEX
dx --dex --output=classes.dex [class文件/目录/jar包路径]
# 示例:将 libs 目录下的 jar 包转为 DEX
dx --dex --output=classes.dex libs/xxx.jar
淘汰核心原因
- 性能差:算法未优化,编译效率远低于 D8;
- 兼容性弱:无法适配 Java 8+ 新特性,增加开发成本;
- 功能单一:仅做基础转换,无优化、混淆等现代化构建需求的支持;
- Google 战略:推出 D8/R8 构建更高效、功能更完整的编译体系。
开发者注意事项
- 绝对不建议在新项目中使用,即使是旧项目迁移,也优先切换到 D8/R8;
- 若需兼容极旧版 AGP(< 3.0)或 Android 设备(< 4.0),可临时保留,但需做好兼容测试;
- 从 dx 迁移到 D8 无需大幅修改代码,仅需升级 AGP 到 3.1+,AGP 会自动替换编译工具。
各种DEX编译器比较
Android 专属的 DEX 编译器核心分为历史工具和现代工具两类,核心目标都是将 Java/Kotlin 字节码(.class/.jar)转换为 Android 运行时(Dalvik/ART)可执行的 DEX 字节码(.dex),但在功能、性能、兼容性上差异显著。以下是完整梳理:
历史级 DEX 编译器:dx(已废弃)
1. 核心定位
dx 是 Android 早期(AGP 3.0 之前)的唯一官方 DEX 编译器,全称 dx tool,由 Google 基于 Apache Harmony 项目开发,是 Android 构建流程中 “class → dex” 的核心工具。
2. 核心特点
- 功能单一:仅完成基础的字节码转 DEX,无优化、无 Java 8+ 特性支持;
- 性能缺陷:构建速度慢(尤其是大型项目),生成的 DEX 文件体积大;
- 兼容性差:对 Java 8 的 Lambda、Stream 等新特性完全不支持,需依赖第三方库(如 retrolambda)做语法兼容;
- 废弃背景:Google 在 AGP 3.0 中推出 D8 替代 dx,AGP 3.1 后将 D8 设为默认,AGP 7.0 后完全移除 dx 支持。
3. 典型使用(仅作历史参考)
# 旧版 dx 命令(已废弃)
dx --dex --output=classes.dex my-classes/
现代核心 DEX 编译器:D8
1. 核心定位
D8(D8 Dex Compiler)是 Google 在 AGP 3.0 推出的新一代基础 DEX 编译器,核心目标是替代 dx,专注于 “高效、优化的 class → dex 转换”,也是 R8 的基础组件。
2. 核心优势(对比 dx)
- 速度更快:增量编译支持 + 优化的算法,大型项目构建速度提升 20%~50%;
- 体积更小:优化字节码结构,减少冗余指令,DEX 体积平均降低 10%~15%;
- 兼容性强:内置 Java 8+ 特性 “脱糖”(Desugaring),无需第三方库即可支持 Lambda、方法引用等;
- 多 DEX 支持:自动处理 65536 方法数限制,拆分多 DEX 文件(classes2.dex、classes3.dex 等)。
3. 核心特性
- 仅聚焦 “转换 + 基础脱糖”,不负责代码混淆、压缩、深度优化;
- 完全内置在 AGP 中,AGP 3.1+ 默认可用,无需手动安装;
- 支持命令行手动调用(高级场景)。
一站式优化型 DEX 编译器:R8
1. 核心定位
R8 是 Google 在 AGP 3.4 推出的全功能 DEX 编译优化工具,并非单纯的 “DEX 编译器”,而是 “D8 + 代码压缩 + 混淆 + 深度优化” 的整合体,其核心底层仍依赖 D8 的 class → dex 转换能力。
2. 核心优势(对比 D8)
- 包含 D8 的所有 DEX 转换能力,且新增:
- 代码压缩(移除死代码);
- 代码混淆(类 / 方法名重命名);
- 深度优化(方法内联、常量折叠、控制流简化等);
- 构建速度比 “D8 + ProGuard” 更快(统一流程,减少中间步骤);
- AGP 7.0+ 后成为默认工具,完全替代 “D8 + ProGuard” 组合。
3. 关键区别(D8 vs R8)
| 维度 | D8 | R8 |
|---|---|---|
| 核心目标 | 纯 DEX 转换 | 转换 + 压缩 + 混淆 + 优化 |
| 功能边界 | 仅 “class → dex” | 一站式编译优化 |
| 混淆 / 压缩 | 不支持 | 原生支持 |
| 优化深度 | 基础(仅 DEX 结构优化) | 深度(跨方法 / 跨类优化) |
补充:DEX 编译器的衍生工具 / 模式
1. R8 Full Mode(R8 全量优化模式)
- 是 R8 的增强模式,通过
android.enableR8.fullMode=true开启; - 更严格地移除死代码(包括跨模块的冗余代码),进一步减小 DEX 体积;
- 注意:需确保反射调用的代码已显式保留,否则易导致运行时崩溃。
2. D9(Android 10+ 新增,针对 ART 优化)
- D9 是 D8 的升级版,全称
D9 Dex Compiler,针对 Android 10+ 的 ART 虚拟机做了深度优化; - 生成的 DEX 兼容 ART 的 “快速解释器” 和 “AOT 编译”,运行性能更高;
- 无需手动配置,AGP 4.0+ 会根据目标 Android 版本自动选择 D8/D9。
总结:DEX 编译器的演进与选型
| 工具 | 状态 | 核心场景 | 推荐度 |
|---|---|---|---|
| dx | 已废弃 | 仅兼容极旧版 AGP(❤️.0) | ❌ |
| D8 | 主流基础 | 仅需纯 DEX 转换,无需优化 / 混淆 | ✅(基础场景) |
| R8 | 主流首选 | 完整的 Android 构建优化(转换 + 压缩 + 混淆) | ✅✅(绝大多数场景) |
| D9 | 自动适配 | Android 10+ 设备的 DEX 优化 | ✅(AGP 自动处理) |
开发者选型建议
- 普通项目:直接使用 AGP 默认的 R8(无需额外配置),兼顾 DEX 转换、体积优化、代码混淆;
- 仅需纯 DEX 转换(如手动打包小工具):单独使用 D8 命令行工具;
- 极旧项目迁移:先从 dx 切换到 D8,再逐步升级到 R8;
- Android 10+ 适配:无需手动干预,AGP 会自动用 D9 优化 DEX 生成。
所有现代 DEX 编译器均内置在 Android Gradle Plugin 中,无需手动安装,仅需关注反射、多 DEX 等场景的配置兼容即可。
Android 核心编译模式
Android 的 “核心编译模式” 需从两个维度梳理:
一是应用代码到可执行产物的编译流程模式(前端编译,对应开发者构建 APK/AAB 的过程) 二是应用运行时的字节码执行编译模式(后端编译,对应 ART/Dalvik 执行 DEX 的方式)
以下是完整且易理解的分类总结:
- 开发者无需手动切换 ART 的运行时编译模式(系统自动适配)。
- 构建期编译模式的核心优化方向是:用 R8 替代纯 D8,开启增量编译,对原生模块做 PGO 优化。
- Android 14+ 进一步强化了 “编译沙箱” 和 “增量 AOT”,减少应用更新后的编译耗时。
核心维度 1:运行时编译模式(ART/Dalvik 执行 DEX 的方式)
这是 Android 最具特色的编译模式,直接决定应用运行性能,也是开发者最常接触的核心概念:
| 编译模式 | 英文全称 | 核心逻辑 | 适用场景 |
|---|---|---|---|
| 解释执行 | Interpretation | 逐行解析 DEX 字节码并执行,无需编译为机器码 | 低频 / 冷启动代码、低性能设备 |
| JIT(即时编译) | Just-In-Time Compilation | 运行时识别 “热点代码”(高频执行),临时编译为机器码并缓存,应用退出后缓存失效 | Dalvik 全量、ART 补充 |
| AOT(预编译) | Ahead-Of-Time Compilation | 应用安装 / 更新时,提前将 DEX 字节码编译为机器码(.oat 文件),运行时直接执行 | ART 核心(Android 5.0+) |
| 混合编译 | Mixed Compilation | ART 结合 AOT + JIT + 解释执行 + PGO(配置文件引导编译),按需优化 | Android 7.0+ 主流模式 |
关键补充(混合编译的核心逻辑):
Android 7.0 后 ART 不再无脑全量 AOT 编译,而是:
- 应用首次安装:仅用解释执行,同时记录用户高频操作(PGO 配置文件);
- 设备空闲 / 充电时:根据 PGO 对热点代码做 AOT 编译;
- 运行时:低频代码用解释执行,未预编译的热点代码临时 JIT 编译;
- 持续优化:根据用户使用习惯动态更新 PGO 和 AOT 编译范围。
核心维度 2:构建期编译模式(开发者打包 APK/AAB 的方式)
这是从 Java/Kotlin 源码到 DEX / 机器码的前端编译流程,核心分为以下几类:
| 编译模式 | 核心目标 | 典型工具 / 场景 | |
|---|---|---|---|
| JVM 编译 → DEX 转换 | 将 Java/Kotlin 源码编译为 JVM .class 字节码,再通过 D8/R8 转为 DEX | 主流模式(99% 安卓项目),AGP 默认流程 | |
| 直接编译为 DEX | 跳过 JVM .class 阶段,直接将 Kotlin 源码编译为 DEX(无中间字节码) | Kotlin/JS 跨平台、小众轻量项目 | |
| 原生编译(NDK) | Native Compilation | 将 C/C++ 源码编译为机器码(.so 文件),不经过 DEX 环节,由 ART 直接加载 | 高性能场景(音视频、游戏、算法) |
| AOT 预编译(构建期) | 构建时提前将 DEX 编译为特定架构的机器码,减少设备端 AOT 耗时 | Android App Bundle(AAB)的 “编译为原生代码” 选项、定制化 ROM 开发 | |
| 增量编译 | Incremental Compilation | 仅编译本次修改的源码 / 资源,而非全量重建 | 开发阶段提速(AGP 内置支持) |
| 全量编译 | Full Compilation | 清空缓存,重新编译所有源码 / 资源,保证产物纯净 | 打包发布、缓存异常时使用 |
延伸:特殊编译模式(小众但核心)
1. 提前编译(Profile Guided Optimization,PGO)
- 不是独立编译模式,而是 “编译优化策略”;
- 核心:先运行应用收集性能数据(热点方法、分支走向),再基于数据做针对性编译优化(如方法内联、常量折叠);
- 应用场景:R8 Full Mode、ART 混合编译、NDK 原生编译优化。
2. 即时编译(JIT)的进阶:JIT Cache 持久化
- Android 10+ 新增特性,将 JIT 编译的机器码缓存持久化到设备,应用重启后无需重新编译;
- 进一步平衡启动速度和运行性能。
3. 动态编译(Dynamic Compilation)
- 应用运行时动态生成 DEX 字节码并编译执行(如插件化、热修复);
- 需通过
DexClassLoader/PathClassLoader加载,受 Android 签名 / 权限限制。
核心编译模式总结(开发者视角)
| 场景 | 核心编译模式 | 关键工具 / 注意点 |
|---|---|---|
| 日常开发 / 打包 | JVM 编译→D8/R8 转 DEX + ART 混合编译 | AGP 自动处理,无需手动配置 |
| 高性能原生模块 | NDK 原生编译 | 需编写 C/C++ 代码,适配不同 CPU 架构 |
| 优化应用运行性能 | 基于 PGO 的 ART 混合编译 | 避免过度反射,确保热点代码被正确识别 |
| 提速开发构建 | 增量编译 | Android Studio 默认开启 |