dependencies{implementation"com.google.guava:guava:31.0.1-android"// To use CallbackToFutureAdapterimplementation"androidx.concurrent:concurrent-futures:1.3.0"// Kotlinimplementation"org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0"}
Kotlin
dependencies{implementation("com.google.guava:guava:31.0.1-android")// To use CallbackToFutureAdapterimplementation("androidx.concurrent:concurrent-futures:1.3.0")// Kotlinimplementation("org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0")}
valfuture:ListenableFuture<QueryResult>=...Futures.addCallback(future,object:FutureCallback<QueryResult>{overridefunonSuccess(result:QueryResult){// handle success}overridefunonFailure(t:Throwable){// handle failure}},// causes the callbacks to be executed on the main (UI) threadcontext.mainExecutor)
Java
ListenableFuture<QueryResult>future=...Futures.addCallback(future,newFutureCallback<QueryResult>(){publicvoidonSuccess(QueryResultresult){// handle success}publicvoidonFailure(@NonNullThrowablethrown){// handle failure}},// causes the callbacks to be executed on the main (UI) threadcontext.getMainExecutor());
[null,null,["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# Using a ListenableFuture\n\nA `ListenableFuture` represents the result of an asynchronous computation: a\ncomputation that may or may not have finished producing a result yet. It's a\ntype of [Future](https://developer.android.com/reference/java/util/concurrent/Future)\nthat allows you to register callbacks to be executed once the computation is\ncomplete, or if the computation is already complete, immediately.\n\n`ListenableFuture` is not part of the Android framework and is instead provided\nby [Guava](https://github.com/google/guava). For more information about the\nimplementation of this class, see [ListenableFuture explained](https://github.com/google/guava/wiki/ListenableFutureExplained).\n\nMany existing Jetpack libraries such as [CameraX](/jetpack/androidx/releases/camera)\nor [Health Services](/training/wearables/health-services) have asynchronous methods\nwhere the return type is a `ListenableFuture` which represents the status of\nthe execution. In some cases you may need to implement a method that returns a\n`ListenableFuture`, such as to satisfy the requirements of [`TileService`](/reference/androidx/wear/tiles/TileService).\n| **Tip:** Check if the Jetpack library you're using has a `-ktx` artifact, as these often contain built-in wrappers for `ListenableFuture`-based methods. For example, `androidx.work:work-runtime-ktx` provides wrappers for WorkManager APIs as suspend functions.\n\nRequired libraries\n------------------\n\n### Groovy\n\n```groovy\ndependencies {\n implementation \"com.google.guava:guava:31.0.1-android\"\n\n // To use CallbackToFutureAdapter\n implementation \"androidx.concurrent:concurrent-futures:1.3.0\"\n\n // Kotlin\n implementation \"org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0\"\n}\n```\n\n### Kotlin\n\n```kotlin\ndependencies {\n implementation(\"com.google.guava:guava:31.0.1-android\")\n\n // To use CallbackToFutureAdapter\n implementation(\"androidx.concurrent:concurrent-futures:1.3.0\")\n\n // Kotlin\n implementation(\"org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0\")\n}\n```\n\nGetting the result of a `ListenableFuture`\n------------------------------------------\n\n### Adding a callback\n\nUse the [`Futures.addCallback(...)`](https://guava.dev/releases/snapshot/api/docs/com/google/common/util/concurrent/Futures.html#addCallback(com.google.common.util.concurrent.ListenableFuture,com.google.common.util.concurrent.FutureCallback,java.util.concurrent.Executor))\nhelper method to attach success and failure callbacks onto a `ListenableFuture`. \n\n### Kotlin\n\n```kotlin\nval future: ListenableFuture\u003cQueryResult\u003e = ...\nFutures.addCallback(\n future,\n object : FutureCallback\u003cQueryResult\u003e {\n override fun onSuccess(result: QueryResult) {\n // handle success\n }\n\n override fun onFailure(t: Throwable) {\n // handle failure\n }\n },\n // causes the callbacks to be executed on the main (UI) thread\n context.mainExecutor\n)\n```\n\n### Java\n\n```java\nListenableFuture\u003cQueryResult\u003e future = ...\nFutures.addCallback(\n future,\n new FutureCallback\u003cQueryResult\u003e() {\n public void onSuccess(QueryResult result) {\n // handle success\n }\n\n public void onFailure(@NonNull Throwable thrown) {\n // handle failure\n }\n },\n // causes the callbacks to be executed on the main (UI) thread\n context.getMainExecutor()\n);\n```\n\n### Suspending in Kotlin\n\nWhen using Kotlin, the easiest way to wait for the result of a ListenableFuture\nis to use [`await()`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-guava/kotlinx.coroutines.guava/await.html). \n\n```kotlin\nimport kotlinx.coroutines.guava.await\n\n...\n\nval future: ListenableFuture\u003cQueryResult\u003e = ...\nval queryResult = future.await() // suspends awaiting success\n```\n\n### Interop with RxJava\n\nAn RxJava [`Single`](https://reactivex.io/documentation/single.html)\ncan be created from a `ListenableFuture` by registering callbacks inside a\n[`SingleEmitter`](https://reactivex.io/RxJava/javadoc/io/reactivex/SingleEmitter.html). \n\n### Kotlin\n\n```kotlin\nval future: ListenableFuture\u003cQueryResult\u003e = ...\nval single = Single.create\u003cQueryResult\u003e {\n Futures.addCallback(future, object : FutureCallback\u003cQueryResult\u003e {\n override fun onSuccess(result: QueryResult) {\n it.onSuccess(result)\n }\n\n override fun onFailure(t: Throwable) {\n it.onError(t)\n }\n }, executor)\n}\n```\n\n### Java\n\n```java\nListenableFuture\u003cQueryResult\u003e future = ...\nSingle\u003cQueryResult\u003e single = Single.create(\n e -\u003e Futures.addCallback(future, new FutureCallback\u003cQueryResult\u003e() {\n @Override\n public void onSuccess(QueryResult result) {\n e.onSuccess(result);\n }\n\n @Override\n public void onFailure(@NonNull Throwable thrown) {\n e.onError(thrown);\n }\n }, executor));\n```\n\nCreating a `ListenableFuture`\n-----------------------------\n\n### Creating an immediate future\n\nIf your API is not asynchronous, but you need to wrap the result of a completed\noperation into a `ListenableFuture`, you can create an `ImmediateFuture`. This\ncan be done using the [`Futures.immediateFuture(...)`](https://guava.dev/releases/snapshot/api/docs/com/google/common/util/concurrent/Futures.html#immediateFuture(V))\nfactory method.\n**Warning:** This sample code is only recommended when the result is available *immediately* . `ImmediateFuture` shouldn't be used in synchronous APIs, such as when `getQueryResult()` is a long-running blocking call. \n\n### Kotlin\n\n```kotlin\nfun getResult(): ListenableFuture\u003cQueryResult\u003e {\n try {\n val queryResult = getQueryResult()\n return Futures.immediateFuture(queryResult)\n } catch (e: Exception) {\n return Futures.immediateFailedFuture(e)\n }\n}\n```\n\n### Java\n\n```java\npublic ListenableFuture\u003cQueryResult\u003e getResult() {\n try {\n QueryResult queryResult = getQueryResult();\n return Futures.immediateFuture(queryResult);\n } catch (Exception e) {\n return Futures.immediateFailedFuture(e);\n }\n}\n```\n\n### Using a coroutine\n\nIn Kotlin, a [`future{ ... }`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-guava/kotlinx.coroutines.guava/future.html)\ncan be used to convert the result of a suspend function into a `ListenableFuture`. \n\n```kotlin\nimport kotlinx.coroutines.guava.future\n\nsuspend fun getResultAsync(): QueryResult { ... }\n\nfun getResultFuture(): ListenableFuture\u003cQueryResult\u003e {\n return coroutineScope.future{\n getResultAsync()\n }\n}\n```\n\n### Converting a callback\n\nTo convert a callback-based API into one that uses `ListenableFuture`, use\n[`CallbackToFutureAdapter`](/reference/androidx/concurrent/futures/CallbackToFutureAdapter).\nThis API is provided by the `androidx.concurrent:concurrent-futures` artifact.\n\nSee [androidx.concurrent](/jetpack/androidx/releases/concurrent) for more information.\n\n### Converting from RxJava `Single`\n\nWhen using RxJava, a [`Single`](https://reactivex.io/documentation/single.html)\ncan be converted into a [`SettableFuture`](https://guava.dev/releases/snapshot/api/docs/com/google/common/util/concurrent/SettableFuture.html),\nwhich implements `ListenableFuture`. \n\n### Kotlin\n\n```kotlin\nfun getResult(): ListenableFuture\u003cQueryResult\u003e {\n val single: Single\u003cQueryResult\u003e = ...\n\n val future = SettableFuture.create\u003cQueryResult\u003e()\n single.subscribe(future::set, future::setException)\n return future\n}\n```\n\n### Java\n\n```java\npublic ListenableFuture\u003cQueryResult\u003e getResult() {\n Single\u003cQueryResult\u003e single = ...\n\n SettableFuture\u003cQueryResult\u003e future = SettableFuture.create();\n single.subscribe(future::set, future::setException);\n return future;\n}\n```"]]