Lambda expressions in Android (part 2/2)

In the previous post, lambda expressions in Java 8 have been introduced. In this post I will describe how to enable and use Java 8 language features including lambda expressions in Android development.

Until recently, only Java 7 was officially supported when developing for Android. However, this changes with the release of Android N (Nougat, API version 24) and its official support for Java 8. Before Android N was released however, it was also possible to use an external library called retrolambda which allows to bring lambda expressions support to Java 7 and lower.

Android N & Jack toolchain

With the release of Android N, a new toolchain Jack has been published too. Jack toolchain comprises a compiler from Java source to the Android dex file format. Among the features Jack provides are: repackaging, shrinking, obfuscation, multidex and Java 8 support.

Before we begin, first of all, make sure you have Java 8 JDK installed on your system and that you’re running Android Studio 2.1 or higher. Also, you need to set a correct path to JDK installation folder in Android Studio in order to use all the new Java 8 features. In Android Studio go to the main menu File -> Project Structure... and input the path to Java 8 JDK (in my case /usr/lib/jvm/java-1.8.0-openjdk-amd64) like this:

Android Studio JDK location (for setting up the lambda expressions in Android)

In order to let your IDE know that you’re using Java 8 features in your source code, add the compileOptions section to build.gradle. As Jack toolchain is still an experimental tool, it needs to be explicitly enabled in the module-level build.gradle file too:

After this, try to compile and run a simple example of setting an OnClickListener on a Button:

If everything went well, you have successfully set up using Java 8 features including lambda expressions in Android.

Java 8 supported language features

The Android support of Java 8 language is not complete at the time of writing the post. However, all the main features are supported and some of them (like lambda expressions) are also backported to API level 23 and lower (with Jack compiler enabled). Here’s a list of the supported features:

  • Lambda expressions (also for API <= 23)
  • Method references (also for API <= 23)
  • Type annotations (also for API <= 23)
  • Default and static interface methods
  • Repeatable annotations

Other than the listed, it’s worth mentioning that Stream API is also supported as well as some other features (for a full list, please refer to the official documentation).

Retrolambda

Before Java 8 was officially supported in Android, the only way how to use Java 8 language features, specifically lambda expressions, was to use an external library like retrolambda [link] together with gradle-retrolambda [link]. Even now, when Java 8 is officially supported, there might be cases when you need to use the library instead.

The author explains how retrolambda works on his GitHub page:

Retrolambda lets you run Java 8 code with lambda expressions, method references and try-with-resources statements on Java 7, 6 or 5. It does this by transforming your Java 8 compiled bytecode so that it can run on an older Java runtime. After the transformation they are just a bunch of normal .class files, without any additional runtime dependencies.

To set up retrolambda in Android Studio, follow these steps. Again, you will need to set the path to Java 8 JDK in Android Studio. Then, in the project-level build.gradle file, add the following lines so that it looks like this:

The module-level build.gradle file should contain following:

After that, you should be all set to use lambda expressions in Android and Java version lower than 8.

Conclusion

In this post, two ways of enabling the usage of Java 8 language features including lambda expressions in Android development have been presented (see my post on lambda expression in Java 8 too). First, the official Java 8 support that comes with Android N and Jack toolchain and the second, provided by an external libraries retrolambda and gradle-retrolambda.

Sources

Share this:

2 thoughts on “Lambda expressions in Android (part 2/2)

  1. Thank you for this introduction, Milan. I guess it’s a good time now to switch to Jack.
    The problem is that the Java 8 APIs (in opposite to some of the language features) do not exist in SDK v <= 23. Do you know if there is a compatibility library for those APIs that I use instead of the original packages if I develop a backwards compatible app? At least, is there a way to make streams, execution stages, completable futures work on all Android versions?

    • Hi Andi,
      even though the support exists for Jack, there are still some issues which might block you in using Jack just yet. For example missing Java 8 language features, or for me, more important drawback – incompatibility with the data binding support library.

      For now, one of the options you have is not to move to Jack yet and instead use libraries like retrolambda for lambda expressions and Lightweight-Stream-API or streamsupport for streams. Furthermore, there’s also a back-port of the new Java 8 Date and Time API for Android called ThreeTenABP. One of my next posts will be about this particular library.

Leave a Comment

Follow me: