Android - 在 @aar 包中解析类

8

我正在尝试从我的库中构建一个@aar包,以便在客户端项目中用作依赖。

在我的库模块中,我正在使用:

compileOptions{
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

我希望在客户端依赖项中使用之前,对代码进行去糖和使其兼容Java 7。这意味着我需要提供一个 @aar 包,其中 Lambda 函数和所有其他与 Java 8 相关的功能已经转换为 Java 7 字节码。
我面临的问题是,在使用以下库模块时:
apply plugin: 'com.android.library'

desugaring 任务未执行,这意味着字节码包含了 Java 8 相关的导入,例如:

java.lang.invoke.LambdaMetafactory

这将强制我的客户更新编译选项为JavaVersion.VERSION_1_8,而这是我想避免的。

所以作为最后一个问题: desugaring任务是由'com.android.library'插件执行还是仅在'com.android.application'插件中可用?如果是这种情况,您能否帮助我提供一些提示,以便我也可以将此步骤包含到库插件中?


2
你解决了吗? - black
2个回答

1

为了避免在aar文件中包含.archive的.class文件(而不是.dex文件),'com.android.library'插件故意不执行desugaring任务。因此,在这里不会应用desugaring(以及dexing)。

当然,在库项目中,仍然需要指定Java 8支持选项,尽管它们实际上并不重要(只会有javac步骤,没有desugaring / dexing,为了生成.aar文件):

enter image description here

更新:经过再次思考,我现在确信这是“com.android.library”插件中的一个错误。解糖仍然会产生.class文件,因此如果gradle.build配置要求跳过解糖步骤,则没有强烈的理由跳过解糖步骤。

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_7
}

1
我认为 Android 构建工具只是使用来自 Bazel 的 'desugar' 项目来解析 Java8 语法(在 D8 诞生之前)。因此,我们可以将其作为命令行工具来使用以解析我们的代码。 步骤: 1. 下载并安装 Bazel 2. 构建 desugar.jar 3. 使用你的输入(从 aar 中提取出的 classes.jar)执行 desugar.jar 4. 将解析后的 jar 文件放回 aar 中。
以下是相关资源链接:

https://github.com/bazelbuild/bazel/tree/1f684e1b87cd8881a0a4b33e86ba66743e32d674/src/tools/android/java/com/google/devtools/build/android/desugar

https://github.com/bazelbuild/bazel/issues/2975

我猜我们可以把所有这些步骤放进一个Gradle任务中,或者使用“com.android.application”中的现有任务。但我还没有调查过。
另外,我认为不对aar进行解糖是出于设计考虑,而不是错误。因为它为应用程序提供了更多的灵活性,以决定是否解糖(如果应用程序minSdk >=24,则根本不需要对库进行解糖)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接