ListenableFuture を使用する

ListenableFuture は、非同期計算の結果を表します。 まだ結果の生成が完了していない場合も、完了していない場合もあります。Google Future のタイプ には、計算の完了後に実行するコールバックを登録できます。 計算がすでに完了している場合は即時に処理が行われます。

ListenableFuture は Android フレームワークの一部ではなく、提供されます。 (Guava)詳細については、 このクラスの実装については、ListenableFuture の説明をご覧ください。

既存の多くの Jetpack ライブラリ(CameraX など) またはヘルスサービスには非同期メソッドがあります。 戻り値の型は ListenableFuture で、これはサービスのステータス 示されます。場合によっては、 ListenableFutureTileService の要件を満たすなど)

<ph type="x-smartling-placeholder">

必要なライブラリ

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;
}