32

I can use retrolambda to enable lambdas with Android API level <24. So this works

myButton.setOnClickListener(view -> Timber.d("Lambdas work!")); 

This also works

Runnable runLater = () -> Timber.d("Lambdas work!"); runLater.run(); 

But this one does not

Consumer<Integer> runLaterWithInt = (Integer i) -> Timber.d("i = " + i); runLaterWithInt.accept(3); 

The last one works on Android API Level 24, but on other devices this code causes a crash

java.lang.NoClassDefFoundError: com.retrolambdatry.MainActivity$$Lambda$1 

Instead of using retrolambda I tried to enable Java 8. First two code examples still work, although butterknife stopped working. https://developer.android.com/preview/j8-jack.html#configuration here ava.util.function is said to be supported, but I still get a crash when running the third one, this time it is a little different

java.lang.NoClassDefFoundError: com.retrolambdatry.MainActivity$-void_onCreate_android_os_Bundle_savedInstanceState_LambdaImpl1 
4
  • 1
    Possible duplicate of Does Java 8 work on Android api 23 and above? Commented Jul 27, 2016 at 8:02
  • 3
    The question is poorly titled; lambdas are actually being backported to older Android versions, so you don't need Retrolambda. Just install the new Android Studio and build tools. Commented Jul 27, 2016 at 8:20
  • 1
    Perhaps it is poorly titled. As i understand I don't need retorlambda if I have Android N SDK and I enable Jack compile options. Lambdas work either way. But functional interfaces from 'java.util.function' still don't. Commented Jul 27, 2016 at 9:00
  • The problem is that the Jack compiler prevents the use of the Data Binding Library (see here). That's why many people might not be willing to use Jack at the moment, but Retrolambda as an alternative to get lambda expressions (until the issues will be fixed in a future Android Studio version). Commented Nov 13, 2016 at 20:05

6 Answers 6

27

Not sure if you still need an answer to this question, but others (like myself) might.

As version 3.0, Android Studio natively supports lambda functions and many other Java 8 functions on all API levels, but some (like Functional Interfaces and java.util.function) are still restricted to APIs 24+.

Until that support is expanded, android-retrostreams provides backport support for most of it. This project is an 'upgraded port' of the streamsupport library, which you can also use and has many of the functionalities in android-retrostreams. The streamsupport library supports down to Java 6/7, so you can use it even if you don't have AS 3.0+ or aren't targeting Java 8, but you're probably better off using android-retrostreams in most cases, if you can. You can go through the project's javadocs to see exactly what's offered, but highlights that I've used are java.util.function and java.util.Comparator.

Note that java in the package names is replaced with java9, and some of the class and/or method names may have been changed slightly. For example:

java.util.function becomes java9.util.function,

while

java.util.Comparator becomes java9.util.Comparators (and with slightly different method names and call patterns - but the same functionality).

Sign up to request clarification or add additional context in comments.

5 Comments

Correction: android-retrostreams doesn't work on Java 7 if you have a Java 7 Oracle / OpenJDK VM in mind. It does work on Android devices down to API level 15 or 14 regardless of the Java version that was then current, provided you use Android Studio 3.x and its Java 8 capabilities to develop an app for such devices (it wouldn't work with Android Studio 2.3.x). If you need a Stream API backport that indeed works on a real Java 6 / 7 VM (Sun etc.) you'll have to use streamsupport.
Ah, my bad. The android-retrostreams readme made it sound like they only dropped support for Java 6, and that it would work for Android Studio even if you weren't explicitly targeting Java 8. I never actually tried it, though. I'll edit for clarification, just in case.
How does it matter which Java version you are targeting in Android Studio 3.x? In the end, it's the minSDKVersion that decides whether your app runs on, let's say Marshmallow. So, just to avoid possible confusion: let minSDKVersion = 23 (Marshmallow), then "target" Java 8 in Android Studio 3.x and use android-retrostreams and you'll be fine. What i'm saying is, that the android-retrostreams jar file can't be run on a Java 7 Standard Edition VM (JRE from Oracle, IBM ...)
What I'm trying to say is that you have to target Java 8 anyway if you want use Java 8 language features like lambdas, method references or interface default methods. That's totally dis-connected from the minSDKVersion as long as you do not use API calls (like something from java.util.function) that are specific to Java 8. android-retrostreams brings in replacements for these Java 8 APIs that will even work on Ice Cream Sandwich (which definitely was Java 6).
what's the different with retro-lambda? @VerumCH EDITED: after reading it carefully, retrolambda is lacks support for 3rd-party libs. we should really use the android-retrostreams
13

Android support library(AndroidX) now has Consumer and Supplier:

sadly only these two interfaces gets added as of writing.

Now we have Kotlin, it doesn't require you to specify the functional interface explicitly:

 fun test() { val text = withPrintStream { it.println("Header bla bla ") it.printf("%s, %s, %s,", "a", "b", "c").println() } } // Equivalent to the following code in Java: // Consumer<PrintStream> action; // action.accept(ps); fun withPrintStream(action: (PrintStream) -> Unit): String { val byteArrayOutputStream = ByteArrayOutputStream() val ps = PrintStream(byteArrayOutputStream) action(ps) ps.flush() return byteArrayOutputStream.toString() } 

4 Comments

this is an old question. Kotlin solves this, but at the time of asking Kotlin wasn't really an option.
This answer helped me as I'm stuck with Java for now. Cheers!
This is still helpful as it also works in API Level < 24 when using Java code.
really helpful !!! Along with this library-desugaring needed to add developer.android.com/studio/write/…
3

Android Gradle plugin (AGP) 4.0+ add backported support for java8 packages (such as java.util.function, which added to Android API 24) on low API version:

see https://developer.android.com/studio/write/java8-support#library-desugaring

Adding lines from code below to APP module allows me to use openAPI-generator 5.1.0 produced java jersey API-SDK module with Android API < 24 (I use jersey for better polymorphism support)

android { defaultConfig { // Required when setting minSdkVersion to 20 or lower multiDexEnabled true } compileOptions { // Flag to enable support for the new language APIs coreLibraryDesugaringEnabled true // Sets Java compatibility to Java 8 sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' } 

Comments

2

For alternative, Lightweight-Stream-API also provides backport support. Like android-retrostreams metioned above, you have to replace some package names by using:

com.annimon.stream.function instead of java.util.function

com.annimon.stream.ComparatorCompat instead of java.util.Comparator

Comments

1

Use

import androidx.core.util.Consumer; 

instead of

import java.util.function.Consumer; (requires min API 24) 

Sample implementation

public static void sampleMethod(Consumer<Boolean> isClicked) { isClicked.accept(true); } 

usage of sample implementation

Utils.sampleMethod(new Consumer<Boolean>() { @Override public void accept(Boolean isClicked) { } }); 

Comments

-1
allprojects { repositories { maven { url 'https://jitpack.io' } } } dependencies { compile 'com.github.ipcjs:java-support:0.0.3' } 

code: ipcjs/java-support

3 Comments

what is this and why does it help?
@jpcjs yeah I've already looked at that, but that isn't much of documentation. My question remains ^^ what is this? just a complete copy of android? and why does that work?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.