ListenableFuture özelliğini kullanma

ListenableFuture, eşzamansız hesaplamanın, yani henüz sonuç üretmeyi tamamlamamış veya bitmemiş olabilecek bir hesaplamanın sonucunu temsil eder. Bu, hesaplama tamamlandığında veya hesaplama zaten tamamlandığında yürütülecek geri çağırmaları hemen kaydetmenize olanak tanıyan bir Future türüdür.

ListenableFuture, Android çerçevesinin bir parçası değildir ve Guava tarafından sağlanır. Bu sınıfın uygulanması hakkında daha fazla bilgi için ListenableFuture açıklaması konusuna bakın.

KameraX veya Health Services gibi mevcut Jetpack kitaplıklarının çoğunda eşzamansız yöntemler bulunur. Döndürme türü, yürütme durumunu temsil eden ListenableFuture şeklindedir. Bazı durumlarda, TileService koşullarını karşılamak için ListenableFuture değerini döndüren bir yöntem uygulamanız gerekebilir.

Gerekli kitaplıklar

Modern

dependencies {
    implementation "com.google.guava:guava:31.0.1-android"

    // To use CallbackToFutureAdapter
    implementation "androidx.concurrent:concurrent-futures:1.1.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.1.0")

    // Kotlin
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0")
}

ListenableFuture sonucunu alma

Geri arama ekleme

ListenableFuture öğesine başarı ve başarısız geri çağırmaları eklemek için Futures.addCallback(...) yardımcı yöntemini kullanın.

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 alma

Kotlin kullanırken ListenableFuture'ın 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ışabilirlik

RxJava Single, SingleEmitter içindeki geri çağırmaları kaydederek ListenableFuture öğesinden oluşturulabilir.

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 tamamlanan bir işlemin sonucunu bir ListenableFuture öğesine sarmalamanız gerekiyorsa ImmediateFuture oluşturabilirsiniz. Bu, Futures.immediateFuture(...) fabrika yöntemi kullanılarak yapılabilir.

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 askıya alma işlevinin sonucunu ListenableFuture öğesine dönüştürmek için future{ ... } 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 işlevini kullanın. Bu API, androidx.concurrent:concurrent-futures yapısı tarafından sağlanır.

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

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

RxJava kullanılırken Single, ListenableFuture uygulayan SettableFuture öğesine dönüştürülebilir.

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