d8工具使用

d8

d8 是一种命令行工具,Android Studio 和 Android Gradle 插件使用该工具来将项目的 Java 字节码编译为在 Android 设备上运行的 DEX 字节码,该工具支持您在应用的代码中使用 Java 8 语言功能。

d8 在SDK中的位置:android_sdk/build-tools/version/

一般用法

d8 简单易用,只需要指向要转换为 DEX 字节码的已编译 Java 字节码的路径即可,如下所示。

d8 MyProject/app/build/intermediates/classes/debug/*/*.class

输入字节码可以是 *.class 文件或容器(例如 JAR、APK 或 ZIP 文件)的任意组合。还可以添加 DEX 文件作为 d8 的输入,以将这些文件合并到 DEX 输出中,这在要包含增量构建的输出时很有用。

默认情况下,d8会将Java字节码编译为优化的DEX文件,并在其中包含相关的调试信息,以供在运行时用于调试代码。当然也可以添加可选标记来执行各种操作,例如执行增量构建、指定应编译到主DEX文件中的类,以及指定使用Java8语言功能所需的其他资源对应的路径。

d8 path-to-input-files [options]

options可选标记

选项说明
--debug编译 DEX 字节码时在其中包含调试信息,例如调试符号表。此选项默认处于启用状态。要在 DEX 字节码中包含调试信息,d8 要求输入 Java 字节码中包含此信息。例如,如果您使用 javac 编译代码,则需要传递 -g 标记,以在输出的 Java 字节码中包含调试信息。当为应用或库的发布版本编译 DEX 文件时,请改用下述 --release 标记。
--release编译 DEX 字节码时不包含调试信息。不过,d8 包含在生成堆栈轨迹和记录异常时会用到的一些信息。在为公开发布版本编译字节码时,应该传递此标记。
--output path为 DEX 输出指定所需的路径。默认情况下,d8 会在当前工作目录中输出 DEX 文件。如果您指定 ZIP 或 JAR 文件的路径和名称,则 d8 会创建指定的文件并将 DEX 输出文件包含在其中。如果指定现有目录的路径,则 d8 会将 DEX 文件输出到该目录中。path为必须存在的目录或者以.zip和.jar结尾的文件。
--lib android_sdk/platforms/api-level/android.jar指定指向 Android SDK 的 android.jar 的路径。编译使用了 Java 8 语言功能的字节码时需要使用此标志。
--classpath path指定 d8 在编译项目的 DEX 文件时可能需要使用的类路径资源。特别是在编译使用 Java 8 语言功能的字节码时,d8 会要求您指定特定的资源。
--min-api number指定您希望 DEX 输出文件支持的最低 API 级别。
--intermediate传递此标记,可告知 d8 并非要编译项目的全部 Java 字节码集。此标记在执行增量构建(而不是编译您想在设备上运行的优化 DEX 文件)时非常有用,d8 会创建中间 DEX 文件,并将其存储在指定的输出或默认路径中。

如果要编译要在设备上运行的 DEX 文件,请不要使用此标记,并指定中间 DEX 类的路径作为输入。
--file-per-class将每个类编译到单独的 DEX 文件中。启用此标记后,您只需重新编译已更改的类,从而执行更多增量构建。使用 Android Gradle 插件执行增量构建时,此优化默认处于启用状态。如果您还指定了 --main-dex-list,则无法使用此标记。
--no-desugaring停用 Java 8 语言功能。仅当您不想编译使用 Java 8 语言功能的 Java 字节码时,才可使用此标记。
--main-dex-list path指定列出 d8 应包含在主 DEX 文件中的类的文本文件,该文件的名称通常为 classes.dex。也就是说,如果您不使用此标记指定类列表,d8 将无法保证主 DEX 文件中会包含哪些类。

由于 Android 系统在启动您的应用时会先加载主 DEX 文件,因此您可以利用此标记将特定的类编译到主 DEX 文件中,从而使它们在应用启动时得到优先加载。这在支持旧版 multidex 时特别有用,因为在加载旧版 multidex 库之前,只有主 DEX 文件中的类在运行时可用。

请注意,该主 DEX 文件仍须满足 64K 引用限制。因此,请确保不要为主 DEX 文件指定太多类,否则会出现编译错误。默认情况下,在使用 --main-dex-list 指定类时,d8 只会包含主 DEX 文件中的类,这是为了便于调试与主 DEX 文件中缺少的类相关的问题。如果您指定的是 --release 模式,则 d8 会尝试在主 DEX 文件中包含尽可能多的其他类(直到达到 64K 限制为止),从而减少打包到应用发布版本中的 DEX 文件的数量。

如果您还指定了 --file-per-class,则无法使用此标记。
--version输出您当前使用的 d8 版本。
--help输出与使用 d8 有关的帮助文本。

执行增量构建

为了在开发过程中提高构建速度(例如提高持续集成 build 的速度),可以指示 d8 仅编译项目的部分 Java 字节码。例如,如果启用了按类 dexing 处理,则只需重新编译自上次构建以来修改过的类。

**注意**:`d8` 无法自动检测哪些字节码文件已被修改过,因此您需要手动指定类列表。

以下命令可执行几个类的增量构建,并启用按类 dexing 处理。该命令还可为增量构建指定输出目录。

d8 MainActivity.class R.class --intermediate --file-per-class --output ~/build/intermediate/dex

d8 在执行增量构建时,会将一些额外的信息存储在 DEX 输出中,等以后完整构建应用时,它会利用这些信息正确地处理 --main-dex-list 选项以及合并 DEX 文件。例如,d8 在处理 Java 8 lambda 类时,会记录为每个输入类创建的 lamdba 类。在执行完整 build 的过程中,当 d8 在主 DEX 文件中包含某个类时,它会查询元数据,以确保为此类创建的所有 lambda 类也包含在主 DEX 文件中。

如果您已在多次增量构建中将项目的所有字节码编译到 DEX 文件中,则可以通过将中间 DEX 文件的目录传递给 d8 来执行完整 build,如下所示。此外,您也可以使用 --main-dex-list 指定想让 d8 编译到主 DEX 文件中的类。由于输入是已编译为 DEX 字节码的一组文件,因此,完成此 build 的速度应该比完成干净 build 更快。

d8 ~/build/intermediate/dex --release --main-dex-list ~/build/classes.txt --output ~/build/release/dex

编译使用了 Java 8 语言功能的字节码

d8 通过一个叫做“脱糖”的编译过程,使您能够在代码中使用 Java 8 语言功能,此过程会将这些实用的语言功能转换为可以在 Android 平台上运行的字节码。

Android Studio 和 Android Gradle 插件包含了 d8 为您启用脱糖所需的类路径资源。不过,从命令行使用 d8 时,您需要手动添加这些资源。

其中一个资源就是目标 Android SDK 中的 android.jar。此资源包含一组 Android 平台 API,您可以使用 --lib 标记来指定该资源的路径。

另一个资源是您项目的部分已编译的 Java 字节码,您目前不打算将这部分字节码编译为 DEX 字节码,但在将其他类编译为 DEX 字节码时需要用到这些字节码。例如,如果代码使用默认和静态接口方法(一种 Java 8 语言功能),则您需要使用此标记来指定您项目的所有 Java 字节码的路径,即使您不打算将所有 Java 字节码都编译为 DEX 字节码也是如此。这是因为 d8 需要根据这些信息来理解您项目的代码并解析对接口方法的调用。

以下代码示例对一个访问默认接口方法的类执行增量构建:

d8 MainActivity.class --intermediate --file-per-class --output ~/build/intermediate/dex
--lib android_sdk/platforms/api-level/android.jar
--classpath ~/build/javac/debug
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值