d8、r8是怎样将class转换为dex的
Table of Contents
在 Android 开发中,
d8
和r8
是将 Java 字节码(.class
文件)转换为 Dalvik 字节码(.dex
文件)的核心工具。以下是详细的流程,包括字节码转换的过程、.dex
文件的结构及其作用。
1. 字节码转换为 Dex 的详细流程
1.1 输入
- .class 文件:由 Java 或 Kotlin 编译器生成的字节码文件,包含类、方法、字段等信息。
1.2 工具
- d8:将
.class
文件转换为.dex
文件,支持基本优化。 - r8:在
d8
的基础上增加了代码混淆、优化和缩减功能。
1.3 转换过程
-
解析.class 文件:
- 读取
.class
文件,解析其中的常量池、类信息、方法、字段等。 - 将 Java 字节码(基于栈的指令集)转换为更适合 Android 的 Dalvik 字节码(基于寄存器的指令集)。
- 读取
-
优化与转换:
- d8:
- 进行基本优化,如删除未使用的代码、内联方法等。
- 将 Java 字节码转换为 Dalvik 字节码。
- r8:
- 在
d8
的基础上,进一步进行代码混淆(重命名类、方法和字段)、缩减(删除未使用的代码)和优化(如方法内联、常量折叠等)。
- 在
- d8:
-
生成.dex 文件:
- 将优化后的字节码转换为 Dalvik 可执行的
.dex
文件。 - 如果代码量较大,可能会生成多个
.dex
文件(即 MultiDex)。
- 将优化后的字节码转换为 Dalvik 可执行的
-
输出:
- .dex 文件:包含优化后的 Dalvik 字节码,供 Android 设备执行。
2. Dex 文件结构
.dex
文件是 Android Dalvik 虚拟机的可执行文件格式,其结构经过高度优化,以减少文件大小和内存占用。以下是.dex
文件的主要组成部分:
2.1 文件头(Header)
- 包含
.dex
文件的元信息,如文件大小、校验和、SHA-1 签名、字符串表偏移量、类定义偏移量等。 - 用于快速验证文件的完整性和解析文件内容。
2.2 字符串表(String Table)
- 存储文件中使用的所有字符串,如类名、方法名、字段名等。
- 通过索引引用字符串,减少重复存储。
2.3 类型表(Type Table)
- 存储所有用到的类型(类、接口、数组等)。
- 每个类型通过字符串表中的索引引用其名称。
2.4 原型表(Proto Table)
- 存储方法的原型信息,包括返回类型和参数类型。
- 用于描述方法的签名。
2.5 字段表(Field Table)
- 存储类中定义的字段信息,包括字段名、类型和访问权限。
2.6 方法表(Method Table)
- 存储类中定义的方法信息,包括方法名、原型、访问权限和代码偏移量。
2.7 类定义表(Class Def Table)
- 存储类的定义信息,包括类名、超类、接口、字段和方法等。
- 每个类通过类型表引用其名称。
2.8 数据区(Data Section)
- 存储实际的字节码指令、注解、调试信息等。
- 字节码指令是基于寄存器的 Dalvik 指令集。
2.9 链接数据区(Link Data)
- 存储动态链接相关的信息,如静态字段和方法的初始化值。
3. Dex 文件的作用
3.1 优化执行效率
- Dalvik 字节码是基于寄存器的指令集,相比 Java 字节码(基于栈的指令集)更高效。
.dex
文件经过优化,减少了内存占用和加载时间。
3.2 减少文件大小
.dex
文件通过共享字符串、类型和方法信息,减少了重复数据。- 多个
.class
文件合并为一个.dex
文件,进一步减小了 APK 的体积。
3.3 支持 Android 运行时
.dex
文件是 Android Dalvik 虚拟机和 ART(Android Runtime)的可执行文件格式。- ART 在安装时会将
.dex
文件转换为本地机器码(AOT 编译),以提高运行效率。
3.4 支持 MultiDex
- 对于大型应用,单个
.dex
文件可能超出方法数限制(65,536 个方法)。 - MultiDex 机制将代码拆分到多个
.dex
文件中,以支持大型应用。
4. 示例:Dex 文件生成与使用
4.1 使用 d8 生成.dex 文件
通过命令行工具d8
将.class
文件转换为.dex
文件:
d8 --output ./out/ ./input/*.class
4.2 使用 r8 进行代码混淆
在 Gradle 中启用r8
进行代码混淆:
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
4.3 查看.dex 文件内容
使用工具(如dexdump
)查看.dex
文件内容:
dexdump -d classes.dex
5. 总结
- d8 和 r8:是将 Java 字节码转换为 Dalvik 字节码的核心工具,
r8
还支持代码混淆和优化。 - .dex 文件:是 Android 平台的可执行文件格式,经过高度优化,支持高效执行和减少文件大小。
- Dex 文件结构:包括文件头、字符串表、类型表、方法表等,通过共享数据和索引引用,减少了重复存储。
- 作用:
.dex
文件是 Android 应用运行的基础,支持 Dalvik 虚拟机和 ART,并通过 MultiDex 机制支持大型应用。
通过理解.dex
文件的生成过程和结构,可以更好地优化 Android 应用的性能和体积。
明天了解一下[[20250124-apk打包过程]]中提到的资源编译, aapt2 是怎样将资源文件编译为 resources.arsc 的