ListenableFuture nutzen

ListenableFuture stellt das Ergebnis einer asynchronen Berechnung dar: eine Berechnung, bei der noch kein Ergebnis erhöht wurde. Es ist ein Typ von Future mit der Sie Callbacks registrieren können, die ausgeführt werden, sobald die Berechnung oder, wenn die Berechnung bereits abgeschlossen ist, sofort.

ListenableFuture ist nicht Teil des Android-Frameworks und wird stattdessen bereitgestellt von Guava. Weitere Informationen zur Implementierung dieser Klasse finden Sie unter ListenableFuture erklärt.

Viele Jetpack-Bibliotheken wie CameraX oder Gesundheitsdienste haben asynchrone Methoden. wobei der Rückgabetyp ein ListenableFuture ist, der den Status die Ausführung. In einigen Fällen müssen Sie möglicherweise eine Methode implementieren, die eine ListenableFuture, um die Anforderungen von TileService zu erfüllen.

<ph type="x-smartling-placeholder">

Erforderliche Bibliotheken

Cool

dependencies {
    implementation "com.google.guava:guava:31.0.1-android"

    // To use CallbackToFutureAdapter
    implementation "androidx.concurrent:concurrent-futures:1.2.0"

    // Kotlin
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0"
}

Kotlin

dependencies {
    implementation("com.google.guava:guava:31.0.1-android")

    // To use CallbackToFutureAdapter
    implementation("androidx.concurrent:concurrent-futures:1.2.0")

    // Kotlin
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0")
}

Ergebnis eines ListenableFuture abrufen

Callback hinzufügen

Verwenden Sie den Futures.addCallback(...). Hilfsmethode zum Anhängen von Erfolgs- und Fehler-Callbacks an ListenableFuture anzufügen.

Kotlin

val future: ListenableFuture<QueryResult> = ...
Futures.addCallback(
    future,
    object : FutureCallback<QueryResult> {
        override fun onSuccess(result: QueryResult) {
            // handle success
        }

        override fun onFailure(t: Throwable) {
            // handle failure
        }
    },
    // causes the callbacks to be executed on the main (UI) thread
    context.mainExecutor
)

Java

ListenableFuture<QueryResult> future = ...
Futures.addCallback(
    future,
    new FutureCallback<QueryResult>() {
        public void onSuccess(QueryResult result) {
            // handle success
        }

        public void onFailure(@NonNull Throwable thrown) {
            // handle failure
        }
    },
    // causes the callbacks to be executed on the main (UI) thread
    context.getMainExecutor()
);

Sperrung in Kotlin

Bei Verwendung von Kotlin ist die einfachste Möglichkeit, auf das Ergebnis eines ListenableFuture zu warten. ist die Verwendung von await().

import kotlinx.coroutines.guava.await

...

val future: ListenableFuture<QueryResult> = ...
val queryResult = future.await() // suspends awaiting success

Interoperabilität mit RxJava

Ein RxJava-Single kann aus einem ListenableFuture erstellt werden, indem Callbacks in einem SingleEmitter

Kotlin

val future: ListenableFuture<QueryResult> = ...
val single = Single.create<QueryResult> {
    Futures.addCallback(future, object : FutureCallback<QueryResult> {
        override fun onSuccess(result: QueryResult) {
            it.onSuccess(result)
        }

        override fun onFailure(t: Throwable) {
            it.onError(t)
        }
    }, executor)
}

Java

ListenableFuture<QueryResult> future = ...
Single<QueryResult> single = Single.create(
        e -> Futures.addCallback(future, new FutureCallback<QueryResult>() {
            @Override
            public void onSuccess(QueryResult result) {
                e.onSuccess(result);
            }

            @Override
            public void onFailure(@NonNull Throwable thrown) {
                e.onError(thrown);
            }
        }, executor));

ListenableFuture wird erstellt

Eine unmittelbare Zukunft schaffen

Wenn Ihre API nicht asynchron ist, Sie aber das Ergebnis einer abgeschlossenen in eine ListenableFuture umwandeln, können Sie ein ImmediateFuture erstellen. Dieses kann mit der Futures.immediateFuture(...) ausgeführt werden. Factory-Methode erstellen.

Kotlin

fun getResult(): ListenableFuture<QueryResult> {
    try {
        val queryResult = getQueryResult()
        return Futures.immediateFuture(queryResult)
    } catch (e: Exception) {
        return Futures.immediateFailedFuture(e)
    }
}

Java

public ListenableFuture<QueryResult> getResult() {
    try {
        QueryResult queryResult = getQueryResult();
        return Futures.immediateFuture(queryResult);
    } catch (Exception e) {
        return Futures.immediateFailedFuture(e);
    }
}

Koroutine verwenden

In Kotlin: Ein future{ ... } kann verwendet werden, um das Ergebnis einer Aussetzungsfunktion in eine ListenableFuture zu konvertieren.

import kotlinx.coroutines.guava.future

suspend fun getResultAsync(): QueryResult { ... }

fun getResultFuture(): ListenableFuture<QueryResult> {
    return coroutineScope.future{
        getResultAsync()
    }
}

Callback konvertieren

Um eine Callback-basierte API in eine API zu konvertieren, die ListenableFuture verwendet, verwenden Sie CallbackToFutureAdapter Diese API wird vom Artefakt androidx.concurrent:concurrent-futures bereitgestellt.

Weitere Informationen finden Sie unter androidx.concurrent.

RxJava Single konvertieren

Wenn Sie RxJava verwenden, wird ein Single kann in ein SettableFuture-, das ListenableFuture implementiert.

Kotlin

fun getResult(): ListenableFuture<QueryResult> {
    val single: Single<QueryResult> = ...

    val future = SettableFuture.create<QueryResult>()
    single.subscribe(future::set, future::setException)
    return future
}

Java

public ListenableFuture<QueryResult> getResult() {
    Single<QueryResult> single = ...

    SettableFuture<QueryResult> future = SettableFuture.create();
    single.subscribe(future::set, future::setException);
    return future;
}