summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com>2024-05-01 22:27:19 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-05-01 22:27:19 +0000
commitd79cc007b8689c6511756d923721f292658b0c20 (patch)
tree6148ce3c151f86350a3682b09deb8fbc90f13f90
parent76c5f49d8fed80389488f0b1f9b9d23f59562e05 (diff)
parent9896fb1bf5a6dc1dc9a5390672b169c4145ef84f (diff)
downloaddocs-master.tar.gz
Merge "Android API guidelines: describe intended use cases for OutcomeReceiver" into mainHEADmastermain
-rw-r--r--api-guidelines/methods.md51
1 files changed, 49 insertions, 2 deletions
diff --git a/api-guidelines/methods.md b/api-guidelines/methods.md
index ca4575a..14ad03a 100644
--- a/api-guidelines/methods.md
+++ b/api-guidelines/methods.md
@@ -1485,6 +1485,55 @@ cautions against using `default` methods in cases where multiple inheritance is
likely; however, this is rare for callbacks and in practice we have only seen
method naming collisions on commonly-extended classes like `Activity`.
+### Use `android.os.OutcomeReceiver` when modeling a non-blocking function call
+
+[`OutcomeReceiver<R,E>`](https://developer.android.com/reference/android/os/OutcomeReceiver)
+reports a result value `R` when successful or `E : Throwable` otherwise - the
+same things a plain method call can do. Use `OutcomeReceiver` as the callback
+type when converting a blocking method that returns a result or throws an
+exception to a non-blocking async method:
+
+```java
+interface FooType {
+ // Before:
+ public FooResult requestFoo(FooRequest request);
+
+ // After:
+ public void requestFooAsync(FooRequest request, Executor executor,
+ OutcomeReceiver<FooResult, Throwable> callback);
+}
+```
+
+Async methods converted in this way always return `void`. Any result that
+`requestFoo` would return is instead reported to `requestFooAsync`'s `callback`
+parameter's `OutcomeReceiver.onResult` by calling it on the provided `executor`.
+Any exception that `requestFoo` would throw is instead reported to the
+`OutcomeReceiver.onError` method in the same way.
+
+Using `OutcomeReceiver` for reporting async method results also affords a simple
+Kotlin `suspend fun` wrapper for async methods using the
+`Continuation.asOutcomeReceiver` extension from `androidx.core:core-ktx`:
+
+```kotlin
+suspend fun FooType.requestFoo(request: FooRequest): FooResult =
+ suspendCancellableCoroutine { continuation ->
+ requestFooAsync(request, Runnable::run, continuation.asOutcomeReceiver())
+ }
+```
+
+Extensions like the above enable Kotlin clients to call non-blocking async
+methods with the convenience of a plain function call without blocking the
+calling thread. These 1-1 extensions for platform APIs may be offered as part of
+the `androidx.core:core-ktx` artifact in Jetpack when combined with standard
+version compatibility checks and considerations. See the documentation for
+[asOutcomeReceiver](https://developer.android.com/reference/kotlin/androidx/core/os/package-summary#(kotlin.coroutines.Continuation).asOutcomeReceiver())
+for more information, cancellation considerations and samples.
+
+Async methods that do not match the semantics of a method returning a result
+or throwing an exception when its work is complete should **not** use
+`OutcomeReceiver` as a callback type. Instead consider one of the other options
+listed below.
+
### Prefer functional interfaces over creating new single abstract method (SAM) types <a name="callbacks-sam"></a>
API level 24 added the `java.util.function.*`
@@ -1501,8 +1550,6 @@ Consider using these generic interfaces, rather than creating new ones:
* `Consumer<T>`: `(T) -> Unit`
* `Function<T,R>`: `(T) -> R`
* `Predicate<T>`: `(T) -> Boolean`
-* [`OutcomeReceiver<R,E>`](https://developer.android.com/reference/android/os/OutcomeReceiver)
- (unary result `R` when successful or `E : Throwable` otherwise)
* [many more available in reference docs](https://developer.android.com/reference/java/util/function/package-summary.html)
#### Placement of SAM parameters