DEV Community

Cover image for Callback to Coroutines in Kotlin
Amit Shekhar
Amit Shekhar

Posted on • Edited on • Originally published at outcomeschool.com

Callback to Coroutines in Kotlin

Hi, I am Amit Shekhar, Co-Founder @ Outcome School • IIT 2010-14 • I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.

In this blog, we will learn how to convert any Callback to Coroutines in Kotlin.

This article was originally published at Outcome School.

We use many libraries in our Android Project that provides the callback way to use instead of the Coroutines way. As nowadays, we all have started using Kotlin Coroutines in our projects, so it becomes our responsibility to implement things in a way that supports Coroutines.

So, we need to learn how to convert any Callback to Coroutines in Kotlin. And, this is the topic of this blog.

Here, I will take an example of a dummy library just for the sake of understanding.

Assume that we can use a library as below:

Library.doSomething(object : Listener {

    override fun onSuccess(result: Result) {

    }

    override fun onError(throwable: Throwable) {

    }

})
Enter fullscreen mode Exit fullscreen mode

Here, the library does a task and we have a listener through which we get the onSuccess and onError callback.

Now, we want to use this library in the Coroutines way.

Let's do this by creating a suspend function as below:

suspend fun doSomething(): Result {
    return suspendCoroutine { continuation ->
        Library.doSomething(object : Listener {

            override fun onSuccess(result: Result) {
                continuation.resume(result)
            }

            override fun onError(throwable: Throwable) {
                continuation.resumeWithException(throwable)
            }

        })
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, it's time to understand what we have done to convert the Callback to Coroutines.

We have followed the following steps to convert the Callback to Coroutines in Kotlin:

  • Create a suspend function to return the Result.
  • Use suspendCoroutine as the return block.
  • Use continuation.resume(result) for the success.
  • Use continuation.resumeWithException(throwable) for the error.

Now, we can use the above function as below:

launch {
    val result = doSomething()
}
Enter fullscreen mode Exit fullscreen mode

This is how we can convert any callback to Coroutines and use them.

Now, we will discuss one more thing: suspendCancellableCoroutine which is different from suspendCoroutine.

Suppose the library also supports the cancellation of the task.

val id = Library.doSomething(object : Listener {

    override fun onSuccess(result: Result) {

    }

    override fun onError(throwable: Throwable) {

    }

})
Enter fullscreen mode Exit fullscreen mode

and, we can use the cancel() method to cancel the task using the id.

Library.cancel(id)
Enter fullscreen mode Exit fullscreen mode

In this case, we will use the suspendCancellableCoroutine instead of the suspendCoroutine.

Now, again, let's convert this Callback to the Coroutines way by creating a suspend function as below:

suspend fun doSomething(): Result {
    return suspendCancellableCoroutine { continuation ->
        val id = Library.doSomething(object : Listener {

            override fun onSuccess(result: Result) {
                continuation.resume(result)
            }

            override fun onError(throwable: Throwable) {
                continuation.resumeWithException(throwable)
            }

        })

        continuation.invokeOnCancellation {
            Library.cancel(id)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

We have followed almost the same steps as we have done for the earlier example except for the following two things:

  • Use the suspendCancellableCoroutine instead of suspendCoroutine.
  • Use continuation.invokeOnCancellation as our library supports the cancellation of the task.
continuation.invokeOnCancellation {
    Library.cancel(id)
}
Enter fullscreen mode Exit fullscreen mode

Now, we can use the above function as below:

launch {
    val result = doSomething()
}
Enter fullscreen mode Exit fullscreen mode

This is how we can convert any callback to Coroutines and use them.

Here as we have a way to cancel the task, so we have used the suspendCancellableCoroutine, else we can simply use the suspendCoroutine.

suspendCancellableCoroutine let us use the invokeOnCancellation that is not supported with the suspendCoroutine.

From the official doc: suspendCancellableCoroutine suspends the coroutine like suspendCoroutine but provides a CancellableContinuation to the block.

Now, we can decide which one to use when based on our use case.

So, today we learned how to convert any callback to Coroutines and use them.

Master Kotlin Coroutines from here: Mastering Kotlin Coroutines

That's it for now.

Thanks

Amit Shekhar

Co-Founder @ Outcome School

You can connect with me on:

Read all of our blogs here.

Top comments (0)