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