ListenableFuture
thể hiện kết quả của một phép tính không đồng bộ: một phép tính có thể đã hoặc chưa hoàn tất việc tạo ra kết quả. Đây là một loại Future
cho phép bạn đăng ký các lệnh gọi lại để thực thi sau khi quá trình tính toán hoàn tất, hoặc nếu quá trình tính toán đã hoàn tất ngay lập tức.
ListenableFuture
không phải là một phần của khung Android mà thay vào đó do Guava cung cấp. Để biết thêm thông tin về cách triển khai lớp này, hãy xem phần Giải thích về ListenableFuture.
Nhiều thư viện Jetpack hiện có như CameraX hoặc Dịch vụ sức khoẻ có các phương thức không đồng bộ, trong đó loại dữ liệu trả về là ListenableFuture
biểu thị trạng thái thực thi. Trong một số trường hợp, bạn có thể cần triển khai phương thức trả về ListenableFuture
, chẳng hạn như để đáp ứng các yêu cầu của TileService
.
Thư viện bắt buộc
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") }
Nhận kết quả của ListenableFuture
Thêm lệnh gọi lại
Sử dụng phương thức trình trợ giúp Futures.addCallback(...)
để đính kèm các lệnh gọi lại thành công và không thành công vào 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() );
Tạm ngưng trong Kotlin
Khi sử dụng Kotlin, cách dễ nhất để đợi kết quả của ListenableFuture là sử dụng await()
.
import kotlinx.coroutines.guava.await ... val future: ListenableFuture<QueryResult> = ... val queryResult = future.await() // suspends awaiting success
Tương tác với RxJava
Bạn có thể tạo một RxJava Single
từ ListenableFuture
bằng cách đăng ký các lệnh gọi lại bên trong một 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));
Tạo một ListenableFuture
Xây dựng tương lai tức thì
Nếu API của bạn không đồng bộ nhưng bạn cần gói kết quả của một thao tác đã hoàn tất vào một ListenableFuture
, thì bạn có thể tạo ImmediateFuture
. Bạn có thể thực hiện việc này bằng cách sử dụng phương thức gốc 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); } }
Sử dụng coroutine
Trong Kotlin, bạn có thể dùng future{ ... }
để chuyển đổi kết quả của hàm tạm ngưng thành ListenableFuture
.
import kotlinx.coroutines.guava.future suspend fun getResultAsync(): QueryResult { ... } fun getResultFuture(): ListenableFuture<QueryResult> { return coroutineScope.future{ getResultAsync() } }
Chuyển đổi một lệnh gọi lại
Để chuyển đổi API dựa trên lệnh gọi lại thành API sử dụng ListenableFuture
, hãy sử dụng CallbackToFutureAdapter
.
API này do cấu phần phần mềm androidx.concurrent:concurrent-futures
cung cấp.
Xem androidx.concurrent để biết thêm thông tin.
Chuyển đổi từ RxJava Single
Khi sử dụng RxJava, Single
có thể được chuyển đổi thành SettableFuture
, giúp triển khai 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; }