Kotlin Coroutines in Android — Part 10

Handling callbacks

Andrea Bresolin
Kin + Carta Created
3 min readApr 5, 2019

--

One of the main benefits of using coroutines is the fact that we can totally avoid any callback. But what if we have some existing code/libraries that make use of callbacks? How can we use them in a coroutine-friendly way? Let’s see how we can achieve this goal.

Let’s assume that we have a class that executes some actions and makes use of callbacks in its methods:

The executeAction() method takes some parameters and also some callbacks that will be called in case of success, error or cancellation.

We have a use case in our Android app and we would like to implement it as a suspend function and just return a result in case of successful execution, throw an exception in case of error or cancel the coroutine in case the action has been cancelled. We can achieve this by making use of suspendCancellableCoroutine(). This function provides an instance of CancellableContinuation to manually resume our coroutine with a result or an exception and we can also cancel it.

Here is an example implementation of our use case:

What happens then when we call execute()? Let’s take a look:

In the above example, we start a coroutine in the main Android UI thread by making use of uiJob from our DSL, then we call the use case that handles the callbacks internally. The execute() method simply returns the result, in case of success, without exposing the callbacks. In case of error, we can catch the exception like with any plain sequential code, while in case of cancellation we can catch our familiar CancellationException.

As we’ve just seen, we’ve transformed some code that requires callbacks into a coroutine-friendly version that doesn’t expose any callback.

Continuation

We’ve used an instance of CancellableContinuation in our example, but what is a continuation?

A continuation can be seen as the rest of the coroutine code after a suspension point.

Continuation is the base interface that represents a continuation. CancellableContinuation is an extension of Continuation that adds support for the cancellation of a coroutine. Having a reference to a Continuation makes it possible to manually control how and when a coroutine is going to resume after suspending.

We can try to visualise a continuation with a simple example:

We have a method that starts a coroutine. Within the coroutine, we have two suspend functions. Each one suspends the coroutine and will make it resume later. (1) is the continuation of suspendFunction1() while (2) is the continuation of suspendFunction2(). The continuation is the block of code after the suspension point.

What’s next

Now we know how to handle code with callbacks to make it more coroutine-friendly and we’ve also seen what a continuation of a coroutine is. In the next part, we’ll have an introduction to channels, another feature of the Kotlin coroutines library.

Get the source code

The source code for this series can be found on GitHub. It’s an example Android project that covers multiple cases. Download it and play with it.

Missed the other parts of this series?

If you’ve missed the other parts of the Kotlin Coroutines in Android series, take a look at the introduction and check the full list of topics.

--

--