ListenableFuture özelliğini kullanma

ListenableFuture, eşzamansız bir hesaplamanın sonucunu temsil eder: a bitmiş veya henüz sonuç üretmemiş daha büyük programlama işlemleri için de geçerlidir. Bu bir Future türü Bu özellik, hesaplama işlemi yapıldıktan sonra yürütülecek geri çağırmaları kaydetmenize olanak tanır. ya da hesaplama işlemi tamamlandıysa derhal bunu yapabilirsiniz.

ListenableFuture, Android çerçevesinin bir parçası değildir ve bunun yerine sağlanmıştır (Guava) Daha fazla bilgi için ListenableFuture açıklaması başlıklı bölüme bakın.

KameraX gibi mevcut birçok Jetpack kitaplığı veya Sağlık Hizmetleri'nin eşzamansız yöntemlere sahip olması burada dönüş türü ListenableFuture ve adım adım anlatılıyor. Bazı durumlarda, ListenableFuture (örneğin TileService şartlarını karşılamak için)

Gerekli kitaplıklar

Modern

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 sonucu alınıyor

Geri çağırma ekleme

Futures.addCallback(...)'ı kullanma ListenableFuture öğesine başarılı ve başarısız geri çağırmalar eklemek için yardımcı yöntem.

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'de askıya alınıyor

Kotlin kullanırken, ListenableFuture sonucunu beklemenin en kolay yolu await() kullanmaktır.

import kotlinx.coroutines.guava.await

...

val future: ListenableFuture<QueryResult> = ...
val queryResult = future.await() // suspends awaiting success

RxJava ile birlikte çalışma

Bir RxJava Single geri çağırmalar kaydedilerek bir ListenableFuture içinden oluşturulabilir. 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 oluşturuluyor

Yakın bir gelecek oluşturma

API'niz eşzamansız değilse ancak tamamlanmış bir işlemi ListenableFuture biçimine dönüştürüyorsanız ImmediateFuture oluşturabilirsiniz. Bu Futures.immediateFuture(...) kullanılarak yapılabilir. fabrika yöntemini kullanarak değiştirebilirsiniz.

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

Eş yordam kullanma

Kotlin'de bir future{ ... } askıya alma işlevinin sonucunu ListenableFuture biçimine dönüştürmek için kullanılabilir.

import kotlinx.coroutines.guava.future

suspend fun getResultAsync(): QueryResult { ... }

fun getResultFuture(): ListenableFuture<QueryResult> {
    return coroutineScope.future{
        getResultAsync()
    }
}

Geri çağırmayı dönüştürme

Geri çağırmaya dayalı bir API'yi ListenableFuture kullanan bir API'ye dönüştürmek için CallbackToFutureAdapter Bu API, androidx.concurrent:concurrent-futures yapısı tarafından sağlanmıştır.

Daha fazla bilgi için androidx.concurrent sayfasına bakın.

RxJava'dan dönüştürülüyor Single

RxJava kullanırken bir Single dönüştürülebilir ve SettableFuture, ve ListenableFuture öğesini uygular.

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