Ein ListenableFuture
stellt das Ergebnis einer asynchronen Berechnung dar: eine Berechnung, die möglicherweise noch kein Ergebnis erzielt hat. Es handelt sich um einen Typ von Future
, mit dem Sie Callbacks registrieren können, die ausgeführt werden sollen, sobald die Berechnung abgeschlossen ist oder die Berechnung bereits abgeschlossen ist.
ListenableFuture
ist nicht Teil des Android-Frameworks und wird stattdessen von Guava bereitgestellt. Weitere Informationen zur Implementierung dieser Klasse finden Sie in der Erläuterung zu ListenableFuture.
Viele vorhandene Jetpack-Bibliotheken wie CameraX oder Health Services haben asynchrone Methoden. Der Rückgabetyp ist dabei ListenableFuture
, der den Status der Ausführung angibt. In einigen Fällen musst du eine Methode implementieren, die ein ListenableFuture
zurückgibt, z. B. um die Anforderungen von TileService
zu erfüllen.
Erforderliche Bibliotheken
Groovig
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 von ListenableFuture
abrufen
Callback hinzufügen
Verwenden Sie die Hilfsmethode Futures.addCallback(...)
, um Erfolgs- und Fehler-Callbacks an eine ListenableFuture
anzuhängen.
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() );
Aussetzen in Kotlin
Bei Verwendung von Kotlin ist es am einfachsten, auf das Ergebnis einer ListenableFuture zu warten, indem du await()
verwendest.
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 einer ListenableFuture
erstellt werden. Dazu werden Callbacks in einem SingleEmitter
registriert.
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 eines abgeschlossenen Vorgangs in eine ListenableFuture
verpacken müssen, können Sie eine ImmediateFuture
erstellen. Dazu kann die Factory-Methode Futures.immediateFuture(...)
verwendet werden.
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 kann ein future{ ... }
verwendet werden, um das Ergebnis einer Anhaltenfunktion in eine ListenableFuture
umzuwandeln.
import kotlinx.coroutines.guava.future suspend fun getResultAsync(): QueryResult { ... } fun getResultFuture(): ListenableFuture<QueryResult> { return coroutineScope.future{ getResultAsync() } }
Callback konvertieren
Verwenden Sie CallbackToFutureAdapter
, um eine Callback-basierte API in eine API umzuwandeln, die ListenableFuture
verwendet.
Diese API wird vom Artefakt androidx.concurrent:concurrent-futures
bereitgestellt.
Weitere Informationen finden Sie unter androidx.gleichzeitig.
Konvertierung von RxJava Single
wird durchgeführt
Bei Verwendung von RxJava kann ein Single
in einen SettableFuture
konvertiert werden, der 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; }