استخدام ListenableFuture

تمثل ListenableFuture نتيجة عملية حسابية غير متزامنة: a عملية حسابية قد تكون أو لم تنته من إنتاج النتيجة بعد. إنها نوع 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

بناء مستقبل مباشر

إذا لم تكن واجهة برمجة التطبيقات غير متزامنة، ولكنك بحاجة إلى التفاف نتيجة اكتمال العملية في 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()
    }
}

تحويل معاودة اتصال

لتحويل واجهة برمجة تطبيقات تستند إلى معاودة الاتصال إلى واجهة تستخدم ListenableFuture، يمكنك استخدام CallbackToFutureAdapter تتوفّر واجهة برمجة التطبيقات هذه من خلال عنصر 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;
}