Native support for java 8 Lambdas on Android

A few months ago I wrote a tutorial about a simple way to incorporate java8 lambda features on Android (which only supports java 6/7 for now).

Well guess what? Android Nougat introduces support for Java 8 language features that you can use when developing apps that target Android version 24 from minSdkVersion 9 and up. We don’t need retrolambda no more :)

Here’s how to enable this feature on your build.gradle:

android {
...
defaultConfig {
...
minSdkVersion 9
...
targetSdkVersion 24
...
jackOptions.enabled true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8

}
}

You can now start writing shorter code…

Lambdas

So things like this:

button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
log("Clicked");
}
}
);

Become this:

button.setOnClickListener(v -> log("Clicked"));

Method References

Sometimes a lambda expression does nothing but call an existing method. In those cases, it’s often clearer to refer to the existing method by name. Method references are compact, easy-to-read lambda expressions for methods that already have a name:

button.setOnClickListener((view) -> deactivate(view));
private void deactivate(View view) {
view.setActivated(false);
}

Can be called as a method reference:

button.setOnClickListener(this::deactivate);

Known issues

Currently there is no support for Instant run nor data binding.

Because Jack does not generate intermediate class files when compiling an app, tools that depend on these files do not currently work with Jack. Some examples of these tools are:

  • Lint detectors that operate on class files;
  • Tools and libraries that require the app’s class files (such as instrumentation tests with JaCoCo).

I’ll personally not ditch retrolambda until instant run is supported but as soon as it is I’ll jump into the bandwagon :)



Hit me with a Tweet if you have any questions