Kotlin Coroutines in Android — Part 8

MVP and MVVM with Clean Architecture

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

--

In this part we’ll focus on applying our DSL to an Android app with MVP or MVVM architecture that also makes use of Clean Architecture. The reason for choosing this specific combination of architectures is due to their general popularity nowadays in the Android world.

Use cases (a.k.a. interactors)

In Clean Architecture, we have use cases (also known as interactors). They allow to split the business logic into smaller pieces that can be used in a modular fashion within a Presenter or a ViewModel.

Remember, as we’ve seen in the previous part, that every method of a Presenter or ViewModel is a candidate for starting a new job. Given that use cases are small units of work that can be used to perform very specific actions, they’re good candidates to implement the tasks of our DSL.

Here is an example of a use case that implements the logic of a sequential task:

It uses the backgroundTask method from our DSL to execute everything on a background thread and then returns the result. The execute() method is a suspend function so it suspends the parent coroutine until the task has completed.

Here is an example of a use case that implements the logic of a task that can be executed in parallel with others:

This task makes use of backgroundTaskAsync and returns a Deferred. For this reason, the name of its execution method respects the convention of ending with the Async suffix. Note that in this case, as opposed to the previous one, we also pass the parent CoroutineScope as an argument and we call backgroundTaskAsync on that scope. This is important to preserve the structured concurrency behaviour as we’ve mentioned in the previous part of this series. Note also that executeAsync() is not a suspend function because this use case returns a Deferred that can be used to suspend the parent coroutine at a later point when we need to wait for the result of the task.

If we need to, we can of course have some sub-tasks within our use cases. Here is an example of a parallel task that also makes a call to a repository within an IO thread:

As you can see, we have a sub-task that uses ioTask from our DSL to fetch some data from a repository by using the thread pool of the IO threads. ioTask suspends until the data of the repository returns, then executeAsync resumes to process the data on a background thread before returning the result of the use case to the caller.

By using our DSL, it’s very easy to offload whatever we want to background threads and interleave multiple tasks executed on different threads without caring about complex details to make the coroutines work properly.

Presenter and ViewModel

The Presenter and ViewModel are our entry points to the coroutines world. They implement CoroutineScope and start new jobs through our DSL. Let’s take a look at an example ViewModel (a Presenter would be the same) that calls some use cases:

Each use case executes a very specific task and all the tasks together contribute to the logic of the job implemented by aMethod(). Anything that is not executed within a use case, runs in the main Android UI thread because we’ve implemented aMethod() through uiJob from our DSL.

You should understand, at this point, how easily we can offload anything to background threads when we don’t specifically need to execute something on the main UI thread. The logic inside the use cases can be written in a simple sequential fashion and with our DSL we can easily switch between different threads to decide where the methods should be executed.

What’s next

We’ve seen how we can combine multiple tasks sequentially with use cases, but those familiar with RxJava might wonder if there’s a way to have a stream-like way of combining them. In the next part, we’ll see how we can make use of the operators on collections provided out of the box by Kotlin to achieve such a stream-like processing.

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.

--

--