Tasks.await
Google Api usually return a Task object, when we use addOnCompleteListener
or addOnSuccessListener
to retrieve the desired result.
val fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)fusedLocationClient.lastLocation .addOnSuccessListener { location : Location? -> // Got last known location. In some rare situations this can be null. }
If we are already in a background thread, we might want to retrieve the result without a callback. Use Tasks.await
to get the result synchronously without callback.
val result = Tasks.await(fusedLocationClient.lastLocation)
You might want to handle the following exception
ExecutionException
- The Task failed, this is the same exception you'd get in a non-blocking failure handler.InterruptedException
- An interrupt occurred while waiting for the task to complete.TimeoutException
- if specified a timeout:Tasks.await(task, 500, TimeUnit.MILLISECONDS)
NOTE: When you use Tasks.await
, the real exception is hidden in ExecutionException.cause
(e.g. java.util.concurrent.ExecutionException: com.google.firebase.FirebaseNetworkException: A network error ...
)
Kotlin Coroutines: Task to Deferred
If you are using kotlin coroutines, you can utiliaze kotlinx-coroutines-play-services.
Include dependencies
dependencies { // https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-play-services implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.2.1'}
Usage
val result = fusedLocationClient.lastLocation.await()
NOTE: Unlike Tasks.await
, you can handle the real exception without the need to look into ExecutionException.cause
.
NOTE: There is also convinient function to change such as Deferred.asTask and Task.asDeferred.
References