一个 ListenableFuture
表示异步计算的结果:一个可能已完成也可能尚未完成产生结果的计算。它是一种 Future
类型,允许您注册回调,以便在计算完成后执行,或者如果计算已完成,则立即执行。
ListenableFuture
不是 Android 框架的一部分,而是由 Guava 提供。有关此类实现的更多信息,请参阅 ListenableFuture 说明。
许多现有的 Jetpack 库(如 CameraX 或 健康服务)具有异步方法,其中返回类型为 ListenableFuture
,表示执行的状态。在某些情况下,您可能需要实现一个返回 ListenableFuture
的方法,例如为了满足 TileService
的要求。
必需库
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") }
获取 ListenableFuture
的结果
添加回调
使用 Futures.addCallback(...)
辅助方法将成功和失败回调附加到 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() );
在 Kotlin 中挂起
在使用 Kotlin 时,等待 ListenableFuture 结果的最简单方法是使用 await()
。
import kotlinx.coroutines.guava.await ... val future: ListenableFuture<QueryResult> = ... val queryResult = future.await() // suspends awaiting success
与 RxJava 的互操作性
可以通过在 SingleEmitter
内部注册回调,从 ListenableFuture
创建 RxJava Single
。
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
创建立即 future
如果您的 API 不是异步的,但您需要将已完成操作的结果包装到 ListenableFuture
中,您可以创建一个 ImmediateFuture
。这可以通过使用 Futures.immediateFuture(...)
工厂方法来完成。
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); } }
使用协程
在 Kotlin 中,可以使用 future{ ... }
将挂起函数的结果转换为 ListenableFuture
。
import kotlinx.coroutines.guava.future suspend fun getResultAsync(): QueryResult { ... } fun getResultFuture(): ListenableFuture<QueryResult> { return coroutineScope.future{ getResultAsync() } }
转换回调
要将基于回调的 API 转换为使用 ListenableFuture
的 API,请使用 CallbackToFutureAdapter
。此 API 由 androidx.concurrent:concurrent-futures
工件提供。
有关更多信息,请参阅 androidx.concurrent。
从 RxJava Single
转换
在使用 RxJava 时,可以将Single
转换为 SettableFuture
,后者实现了 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; }