'Correct way to suspend coroutine until Task<T> is complete

I've recently dove into Kotlin coroutines Since I use a lot of Google's libraries, most of the jobs is done inside Task class

Currently I'm using this extension to suspend coroutine

suspend fun <T> awaitTask(task: Task<T>): T = suspendCoroutine { continuation ->
    task.addOnCompleteListener { task ->
        if (task.isSuccessful) {
            continuation.resume(task.result)
        } else {
            continuation.resumeWithException(task.exception!!)
        }
    }
}

But recently I've seen usage like this

suspend fun <T> awaitTask(task: Task<T>): T = suspendCoroutine { continuation ->
    try {
        val result = Tasks.await(task)
        continuation.resume(result)
    } catch (e: Exception) {
        continuation.resumeWithException(e)
    }
}

Is there any difference, and which one is correct?

UPD: second example isn't working, idk why



Solution 1:[1]

One of the ways to wait for a Task to complete using Kotlin Coroutines is to convert the Task object into a Deferred object by applying Task.asDeferred extension function. For example for fetching data from Firebase Database it can look like the following:

suspend fun makeRequest() {
    val task: Task<DataSnapshot> = FirebaseDatabase.getInstance().reference.get()
    val deferred: Deferred<DataSnapshot> = task.asDeferred()
    val data: Iterable<DataSnapshot> = deferred.await().children

    // ... use data
}

Dependency for Task.asDeferred():

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.5.2'

To call suspend function we need to launch a coroutine:

someCoroutineScope.launch {
    makeRequest()
}

someCoroutineScope is a CoroutineScope instance. In android it can be viewModelScope in ViewModel class and lifecycleScope in Activity or Fragment, or some custom CoroutineScope instance. Dependencies:

implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1