web-dev-qa-db-ja.com

Java 8の機能的インターフェースAndroid 24未満のAPI)を使用する方法はありますか?

Retrolambdaを使用して、Android APIレベル<24でラムダを有効にすることができます。これで機能します

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);

最後の1つはAndroid= APIレベル24で動作しますが、他のデバイスではこのコードによりクラッシュが発生します

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

Retrolambdaを使用する代わりに、Java 8.を有効にしようとしました。最初の2つのコード例は機能しますが、バターナイフは機能しませんでした。 https://developer.Android.com/preview/j8- jack.html#configuration ここにava.util.functionはサポートされていると言われていますが、3つ目を実行するとクラッシュしますが、今回は少し異なります

Java.lang.NoClassDefFoundError: com.retrolambdatry.MainActivity$-void_onCreate_Android_os_Bundle_savedInstanceState_LambdaImpl1
24
sasha199568

この質問に対する答えがまだ必要かどうかはわかりませんが、他の人(私のように)は答える必要があるかもしれません。

バージョン3.0の場合、Android Studio ネイティブにラムダ関数をサポート および他の多くのJavaすべてのAPIレベルで8つの関数ですが、一部(機能インターフェイスと_Java.util.function_)は、引き続きAPI 24以降に制限されています。

そのサポートが拡張されるまで、 Android-retrostreams はそのほとんどにバックポートサポートを提供します。このプロジェクトは streamsupport library の「アップグレードされたポート」であり、これも使用でき、Androidレトロストリームの多くの機能を備えています。 streamsupportライブラリは、Java 6/7までサポートしているため、AS 3.0+を持っていない、またはターゲティングしていない場合でも使用できますJava 8、ただし、可能であれば、ほとんどの場合はAndroidレトロストリームを使用する方が良いでしょう。プロジェクトのjavadocsを調べて、提供されているものを正確に確認できますが、私が使用したハイライトは_Java.util.function_と_Java.util.Comparator_。

パッケージ名のJavaは_Java9_に置き換えられ、クラス名やメソッド名の一部がわずかに変更されている可能性があることに注意してください。例えば:

_Java.util.function_は_Java9.util.function_になります。

ながら

_Java.util.Comparator_は_Java9.util.Comparators_になります(メソッド名と呼び出しパターンが少し異なりますが、機能は同じです)。

22
VerumCH

Androidサポートライブラリ(AndroidX)にConsumerSupplierが追加されました:

悲しいことに これらの2つのインターフェースのみが追加されます 執筆時点。

これで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()
    }
3
lazybug

別の方法として、 Lightweight-Stream-API もバックポートのサポートを提供します。上記の Android-retrostreams のように、以下を使用して一部のパッケージ名を置き換える必要があります。

com.annimon.stream.function の代わりに Java.util.function

com.annimon.stream.ComparatorCompat の代わりに Java.util.Comparator

2
Shen Andrew