Android - @aar包中的Desugar类

时间:2018-01-04 16:43:16

标签: android java-8 android-library aar

我正在尝试从我的库中构建一个@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,这是我想要避免的事情。

作为最后一个问题: 是由'com.android.library'插件执行的desugaring任务还是仅在'com.android.application'插件中可用?如果是这种情况,请你帮我提一些关于我如何将这一步也包含在库插件中的提示?

2 个答案:

答案 0 :(得分:1)

'com.android.library'插件没有故意执行消减任务,因为aar文件包含.class文件的存档(相对于.dex文件)。因此,此处不应用除糖(以及脱胶)。

当然,令人误解的是,在一个图书馆项目中,尽管实际上它们并不重要,但仍然被迫指定Java 8支持选项(无论如何,只有Javac步骤,而不会进行重复/删除),以便生成.aar文件):

enter image description here

更新:第二个想法-我现在确信这 是'com.android.library'插件中的错误。 Desugaring仍会生成.class文件,因此,如果gradle.build config规定了以下步骤,则没有足够的理由跳过desugar步骤:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_7
}

答案 1 :(得分:0)

我认为android构建工具仅使用从bazel到desugar java8语法的'desugar'项目(在D8诞生之前)。因此,我们可以将其用作命令行工具来对我们的代码进行解糖。 脚步: 1.下载并安装bazel 2.建立desugar.jar 3.用您的输入执行desugar.jar(来自您aar的classes.jar) 4.将脱糖罐子放回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中现有的步骤。但是我还没有调查。

更新 此外,我认为不是Desugar aar是设计使然,不是错误。因为它为应用程序决定是否进行脱糖提供了更大的灵活性(如果应用程序minsdk> = 24,则根本不需要对糖库进行脱糖)。