Un ListenableFuture
representa el resultado de un procesamiento asíncrono: un
que puede o no haber terminado de producir un resultado. Es un
tipo de Future
que permite registrar devoluciones de llamada que se ejecutarán una vez que se realice el cálculo
se complete o, si el procesamiento ya está completo, de inmediato.
ListenableFuture
no forma parte del framework de Android y, en su lugar, se proporciona
de Guava. Para obtener más información sobre el
consulta la explicación de ListenableFuture.
Muchas bibliotecas de Jetpack existentes, como CameraX
o los Servicios de salud tienen métodos asíncronos
donde el tipo de datos que se muestra es un ListenableFuture
que representa el estado de
la ejecución. En algunos casos, es posible que debas implementar un método que devuelva un
ListenableFuture
, como para cumplir con los requisitos de TileService
Bibliotecas requeridas
Groovy
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") }
Cómo obtener el resultado de un ListenableFuture
Agrega una devolución de llamada
Usa la Futures.addCallback(...)
.
método auxiliar para adjuntar devoluciones de llamada de éxito y fracaso a un ListenableFuture
.
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() );
Suspensión en Kotlin
Cuando usas Kotlin, la forma más fácil de esperar el resultado de un ListenableFuture
es usar await()
.
import kotlinx.coroutines.guava.await ... val future: ListenableFuture<QueryResult> = ... val queryResult = future.await() // suspends awaiting success
Interoperabilidad con RxJava
Un Single
de RxJava
se pueden crear a partir de un ListenableFuture
registrando devoluciones de llamada dentro de un
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));
Cómo crear un ListenableFuture
Creación de un futuro inmediato
Si tu API no es asíncrona, pero necesitas unir el resultado de una solicitud
en una ListenableFuture
, puedes crear un ImmediateFuture
. Esta
se puede hacer con Futures.immediateFuture(...)
método de fábrica.
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); } }
Usa una corrutina
En Kotlin, un objeto future{ ... }
se puede usar para convertir el resultado de una función de suspensión en un ListenableFuture
.
import kotlinx.coroutines.guava.future suspend fun getResultAsync(): QueryResult { ... } fun getResultFuture(): ListenableFuture<QueryResult> { return coroutineScope.future{ getResultAsync() } }
Cómo convertir una devolución de llamada
Para convertir una API basada en devolución de llamada en una que use ListenableFuture
, usa
CallbackToFutureAdapter
El artefacto androidx.concurrent:concurrent-futures
proporciona esta API.
Consulta androidx.concurrent para obtener más información.
Realiza la conversión de Single
de RxJava
Cuando usas RxJava, se genera un objeto Single
.
se puede convertir en SettableFuture
que implementa ListenableFuture
.
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; }