השדה ListenableFuture
מייצג את התוצאה של חישוב אסינכרוני:
חישוב שצפוי להפיק תוצאה או שלא הפיקו תוצאה עדיין. אלה
סוג של Future
שמאפשר לרשום קריאה חוזרת לביצוע
או אם החישוב כבר הושלם, באופן מיידי.
האפליקציה ListenableFuture
לא נכללת ב-framework של Android אלא מסופקת במקום זאת
מאת Guava. לקבלת מידע נוסף על
על ההטמעה של המחלקה הזו, ראו הסבר על ListenableFuture.
הרבה ספריות Jetpack קיימות כמו CameraX
או לשירותי בריאות יש שיטות אסינכרוניות
כאשר סוג המוחזר הוא ListenableFuture
שמייצג את הסטטוס
בביצוע. במקרים מסוימים ייתכן שתצטרכו להטמיע שיטה שמחזירה
ListenableFuture
, למשל כדי לעמוד בדרישות של TileService
.
ספריות נדרשות
מגניב
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
הוספת קריאה חוזרת (callback)
שימוש בFutures.addCallback(...)
עזר לשיוך קריאות חוזרות (callbacks) שהצליחו או נכשלו ל-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 שלכם לא אסינכרוני, אבל צריך לאפס את התוצאה של
בפעולה 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() } }
המרת קריאה חוזרת (callback)
כדי להמיר ממשק API מבוסס-קריאה חוזרת (callback) ל-API שמשתמש ב-ListenableFuture
, צריך להשתמש ב-
CallbackToFutureAdapter
.
ה-API הזה סופק על ידי פריט המידע שנוצר בתהליך הפיתוח (Artifact) מסוג 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; }