Android 使用dx/d8将jar转换为dex

前言

在 JDK1.8 之前我们可以通过 dx 工具将 jar 转为 dex。
为了能够支持 JDK1.8,目前 AGP 是通过在 D8/R8 将 class 文件编译成 dex 文件的过程中,对字节码进行转换来实现的,这个转换过程称为脱糖。
因此 JDK1.8 及以后我们需要使用 d8 工具将 jar 转为 dex。

dx

dx 位于AndroidSDK/build-tools/<33.0.0的版本号中。

  1. windows 电脑可以直接在目录下执行 dx,mac 需要./dx来执行。
  2. 建议将AndroidSDK/build-tools/<33.0.0的版本号配置到环境变量中。

在这里插入图片描述

如果你的项目使用的 JDK 版本<1.8,你完全可以使用 dx。
如果你的项目使用的 JDK 版本>=1.8,但是不包含 Lambda 等需要脱糖的代码,经实验也可使用 dx。

dx 命令行使用如下:

dx --dex --output=输出 目标.jar

Output name must end with one of: .dex .jar .zip .apk or be a directory.

如:

dx --dex --output=dexlib_dex.jar dexlib.jar

如果报错提示:

Uncaught translation error: com.android.dx.cf.code.SimException: ERROR in com.demon.dexlib.TestActivity.onCreate:(Landroid/os/Bundle;)V: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13)
1 error; aborting

说明你的项目中有需要脱糖的代码。
虽然可以加上–min-sdk-version=26 去解决报错,继续生成 dex。

dx --dex --min-sdk-version=26  --output=dexlib_dex.jar dexlib.jar

但是运行使用会崩溃,因此慎用!!!

java.lang.NoSuchMethodError: No static method metafactory(Ljava/lang/invoke/MethodHandles$Lookup

d8

现在的 Android 项目普遍都是>=JDK1.8,会在 build.gradle 中配置:

compileOptions {
    
    
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
    
    
    jvmTarget = '1.8'
}

d8 位于AndroidSDK/build-tools/>=28.0.1的版本号中。

  1. windows 电脑可以直接在目录下执行 d8,mac 需要./d8来执行。
  2. 建议将AndroidSDK/build-tools/>=28.0.1的版本号配置到环境变量中。
    在这里插入图片描述

d8 命令行使用如下:

d8 --output 输出 目标.jar

Output must be a .zip or .jar archive or an existing directory

如:

d8 --output dexlib_dex.jar dexlib.jar

参考

U8 打包把 dx 替换为 d8
逆向开发使用 dx.jar、d8.jar、baksmali.jar 将 jar 转 dex 文件,解决 requires --min-sdk-version >= 26 (currently 13)问题
ASM 字节码插桩:从 Lambda 表达式讲起

猜你喜欢

转载自blog.csdn.net/DeMonliuhui/article/details/128580370