استفاده از ListenableFuture

ListenableFuture نشان‌دهنده نتیجه یک محاسبه ناهمگام است: محاسبه‌ای که ممکن است هنوز تولید نتیجه را تمام کرده باشد یا نکرده باشد. نوعی از Future است که به شما امکان می‌دهد تماس‌های برگشتی را ثبت کنید تا پس‌از تکمیل محاسبات، یا اگر محاسبات قبلاً تکمیل شده است، بلافاصله اجرا شوند.

‫ListenableFuture بخشی از چارچوب Android نیست و درعوض توسط Guava ارائه می‌شود. برای اطلاعات بیشتر درباره پیاده‌سازی این کلاس، به توضیحات ListenableFuture مراجعه کنید.

بسیاری از کتابخانه‌های Jetpack موجود مانند CameraX یا Health Services دارای روش‌های ناهمگام هستند که نوع پاسخ آن‌ها ListenableFuture است که وضعیت اجرا را نشان می‌دهد. در برخی موارد ممکن است لازم باشد روشی را پیاده‌سازی کنید که ListenableFuture را برمی‌گرداند، مثلاً برای برآورده کردن الزامات TileService.

کتابخانه‌های الزامی

گرووی

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

    // To use CallbackToFutureAdapter
    implementation "androidx.concurrent:concurrent-futures:1.3.0"

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

کاتلین

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

    // To use CallbackToFutureAdapter
    implementation("androidx.concurrent:concurrent-futures:1.3.0")

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

دریافت نتیجه ListenableFuture

درحال افزودن پاسخ تماس

از روش کمکی Futures.addCallback(...) برای پیوست کردن فراخوانی‌های برگشتی موفقیت و شکست به ListenableFuture استفاده کنید.

کاتلین

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
)

جاوا

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

با ثبت کردن فراخوانی‌های برگشتی در SingleEmitter، می‌توان RxJava Single را از ListenableFuture ایجاد کرد.

کاتلین

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

جاوا

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(...) انجام داد.

کاتلین

fun getResult(): ListenableFuture<QueryResult> {
    try {
        val queryResult = getQueryResult()
        return Futures.immediateFuture(queryResult)
    } catch (e: Exception) {
        return Futures.immediateFailedFuture(e)
    }
}

جاوا

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 را پیاده‌سازی می‌کند.

کاتلین

fun getResult(): ListenableFuture<QueryResult> {
    val single: Single<QueryResult> = ...

    val future = SettableFuture.create<QueryResult>()
    single.subscribe(future::set, future::setException)
    return future
}

جاوا

public ListenableFuture<QueryResult> getResult() {
    Single<QueryResult> single = ...

    SettableFuture<QueryResult> future = SettableFuture.create();
    single.subscribe(future::set, future::setException);
    return future;
}