3

We used lots of anonymous class in android project. For example:

new DialogInterface.OnClickListener()

new MediaPlayer.OnPreparedListener()

etc. Is there any way to replace these kinds of anonymous class using new Java lambda expression?

0xAliHn
  • 18,390
  • 23
  • 91
  • 111

3 Answers3

4

You can only replace anon classes for functional interfaces. Lambda expression requires a functional interface i.e. interface that contains only single method.

You have to

  1. enable jack in your app's gradle:

    'defaultConfig { ... jackOptions { enabled true } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }'

  2. now you can replace your anonymous class with lambda expression. for example: replace

    mView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onSomethingClicked();
        }
    });
    

to

 mView.setOnClickListener(view -> onSomethingClicked())

It is important to keep in mind that enabling jack still generates anonymous classes during the compile step. So, be careful about all the leaks you can have with anonymous classes.

Community
  • 1
  • 1
Krupal Shah
  • 8,949
  • 11
  • 57
  • 93
4

With a little configuration via gradle / with external libraries you could use lambda expressions in your Android project.

Out of the box Java 8 Language Features

To start using supported Java 8 language features, update the Android plugin to 3.0.0-alpha1 (or higher).

Android Studio does not support all Java 8 language features, but more are being added in future releases of the IDE. Depending on which minSdkVersion you’re using, certain features and APIs are available now, as described in the table below.

  • Lambda expressions Any.
  • Method References Any.
  • Type Annotations Any.
  • Default and static interface methods Any.
  • Repeating annotations Any.

API level 24 or higher

  • java.lang.annotation.Repeatable .
  • AnnotatedElement.getAnnotationsByType(Class)
  • java.util.stream
  • java.lang.FunctionalInterface
  • java.lang.reflect.Method.isDefault()
  • java.util.function

Further reading: Supported Java 8 Language Features https://developer.android.com/studio/write/java8-support.html

#Jack Compiler for Android

Lately Google announced support for Java 8 features in Android and thanks to Jack compiler you can use lambdas in your code.

Further reading: Use Java 8 Language Features https://developer.android.com/guide/platform/j8-jack.html

Jack is no longer supported, and you should first disable Jack to use the improved Java 8 support built into the default toolchain. https://developer.android.com/studio/write/java8-support.html

Retrolambda

You could alternatively use the external library retrolambda. Which is a backport of Java 8's lambda feature for Java 7,6 and 5.

Kotlin

You could start writing your code in Kotlin / Lambda's with Kotlin.

For further reading, there's a nice article how to handle Lambda's

Community
  • 1
  • 1
Robin Vinzenz
  • 1,247
  • 15
  • 19
1

I have found very nice short code to transform all of the anonymous class with lambda expression. Here is the lambda expression for above mentioned anonymous class:

Anonymous class:

 new DialogInterface.OnClickListener()

Lambda Expression:

(dialog, which) -> 

Anonymous class:

 new MediaPlayer.OnPreparedListener()

Lambda Expression:

mp ->

Isn't it cool...

0xAliHn
  • 18,390
  • 23
  • 91
  • 111