ListenableFuture
は、非同期計算の結果を表します。
まだ結果の生成が完了していない場合も、完了していない場合もあります。Google
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 との相互運用
RxJava Single
関数内にコールバックを登録して、ListenableFuture
から作成できます。
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
の作成
当面の未来を創造する
API が非同期ではないが、完了した 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{ ... }
suspend 関数の結果を 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; }