Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Desugar classes in @aar package

I am trying to build an @aar package from my library to be used as a dependency inside client projects.

In my library module I am using:

compileOptions{
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

I want to desugar the code and to make it Java 7 compatible before reaching in client dependencies. This means I need to actually provide an @aar package where the Lambda functions and all the other Java 8 related features are already ported to Java 7 bytecode.

The problem that I am facing is that on a library module using the:

apply plugin: 'com.android.library'

the desugaring task is not executed, meaning the bytecode contains Java 8 related imports like:

java.lang.invoke.LambdaMetafactory

and this will force my client to update also his compile options to JavaVersion.VERSION_1_8, a thing that I want to avoid.

So as a final question: Is the desugaring task executed by the 'com.android.library' plugin or is this available only into the 'com.android.application' plugin ? If this is the case can you please help me with some hints on how I could include this step also into the library plugin ?

like image 316
Marius Constantin Avatar asked Jan 04 '18 16:01

Marius Constantin


People also ask

Is it possible to include AAR libraries in Gradle?

The jar libraries are inside libs and they work just fine. The aar libraries were added through android studio wizard of adding aar libraries Show activity on this post. Looks like you could do this How to manually include external aar package using new Gradle Android Build System

How do I add AAR or jar files to an app?

Select "Import .JAR or .AAR Package" and click the "Next" button. Find the AAR file using the ellipsis button "..." beside the "File name" field. Keep the app's module selected and click on the Dependencies pane to add the new module as a dependency. Use the "+" button of the dependencies screen and select "Module dependency".

How do I add a module to an existing AAR file?

Find the AAR file using the ellipsis button "..." beside the "File name" field. Keep the app's module selected and click on the Dependencies pane to add the new module as a dependency. Use the "+" button of the dependencies screen and select "Module dependency". Select the module and click "OK".

What is desugaring in Android and why we need it?

So Desugaring is also one of the important features in Android that we should enable in our app which will allow our apps to work in lower API levels as well. So in this article, we will learn about Desugaring. What is Desugaring? Why we need Desugaring? Practical Implementation of Desugaring. What’s happening under the hood? What is Desugaring?


2 Answers

The desugaring task is not executed by the 'com.android.library' plugin on purpose, because an aar file contains an archive of .class files (versus .dex files). So desugaring (as well as dexing) is not applied here.

Of course, what is misleading is that in a library project one is still forced to specify Java 8 support options, despite they actually do not matter (there will be only javac step anyway, without desugaring/dexing, in order to generate .aar file):

enter image description here

UPDATE: on the second thought - I am now convinced this is a bug in the 'com.android.library' plugin. Desugaring still produces .class files, so there is no strong reason for skipping desugar step if that is prescribed by gradle.build config, e.g.:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_7
}
like image 93
Vit Khudenko Avatar answered Oct 19 '22 22:10

Vit Khudenko


I think android build tool just use 'desugar' project from bazel to desugar java8 syntax (before D8 born). So we can just use it as a command line tool to desugar our code. Steps: 1. download and install bazel 2. build desugar.jar 3. execute desugar.jar with your input (classes.jar from you aar) 4. Put desugared jar back into aar.

Here are the resource links:

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

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

I guess we can put all these steps into a gradle task or use existing one in 'com.android.application'. But I haven't investigate it.

UPDATE Besides, I think not desugar aar is by design, not a bug. Because it gives more flexibility for app to decide whether to desugar or not (if app minsdk >=24, no need to desugar library at all).

like image 39
何旭 Eric Avatar answered Oct 19 '22 20:10

何旭 Eric