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
創造立竿見影的未來
如果您的 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
轉換為實作 ListenableFuture
的 SettableFuture
。
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; }