31

我可以使用 retrolambda 来启用 Android API 级别 <24 的 lambda。所以这行得通

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

这也有效

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

但是这个不

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

最后一个适用于 Android API Level 24,但在其他设备上,此代码会导致崩溃

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

我没有使用retrolambda,而是尝试启用Java 8。前两个代码示例仍然有效,尽管butterknife 停止工作。https://developer.android.com/preview/j8-jack.html#configuration这里ava.util.function说支持,但是我运行第三个的时候还是会crash,这次有点不一样

java.lang.NoClassDefFoundError: com.retrolambdatry.MainActivity$-void_onCreate_android_os_Bundle_savedInstanceState_LambdaImpl1
4

5 回答 5

27

不确定您是否仍然需要这个问题的答案,但其他人(比如我自己)可能会。

作为 3.0 版,Android Studio在所有 API 级别上原生支持 lambda 函数和许多其他 Java 8 函数,但一些(如功能接口和java.util.function)仍然仅限于 API 24+。

在扩展该支持之前,android-retrostreams为其中的大部分提供反向端口支持。该项目是streamsupport library的“升级端口” ,您也可以使用它并具有 android-retrostreams 中的许多功能。streamsupport 库支持低至 Java 6/7,因此即使您没有 AS 3.0+ 或不针对 Java 8,您也可以使用它,但在大多数情况下,您最好使用 android-retrostreams,如果你可以。您可以浏览该项目的 javadocs 以确切了解所提供的内容,但我使用的重点是java.util.functionjava.util.Comparator.

请注意,java在包名称中替换为java9,并且某些类和/或方法名称可能已略有更改。例如:

java.util.function变成java9.util.function,

尽管

java.util.Comparator变成java9.util.Comparators(并且方法名称和调用模式略有不同 - 但功能相同)。

于 2018-02-08T13:10:40.010 回答
10

Android 支持库(AndroidX)现在有ConsumerSupplier

遗憾的是,在撰写本文时只添加了这两个接口。

现在我们有了 Kotlin,它不需要您显式指定功能接口:

    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()
    }
于 2019-01-24T09:00:37.807 回答
2

作为替代方案,Lightweight-Stream-API还提供反向端口支持。像上面提到的 android-retrostreams一样,您必须使用替换一些包名称:

com.annimon.stream.functionjava.util.function

com.annimon.stream.ComparatorCompat不是代替java.util.Comparator

于 2018-05-22T08:01:05.127 回答
2

Android Gradle 插件 (AGP) 4.0+ 在低 API 版本上添加了对 java8 包(例如 java.util.function,添加到 Android API 24)的反向支持:

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

将以下代码中的行添加到 APP 模块允许我使用 openAPI-generator 5.1.0 生成的 java jersey API-SDK 模块,Android API < 24(我使用 jersey 以获得更好的多态性支持)

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'
}
于 2021-04-15T10:38:58.793 回答
-1
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
        compile 'com.github.ipcjs:java-support:0.0.3'
}

代码:ipcjs/java-support

于 2017-09-08T11:55:19.793 回答