How to use the new Android coroutine viewModelScope in Clean Architecture

Binding the ViewModel lifecycle to your Use Cases

César Ferreira
May 21 · 3 min read

Kotlin coroutines provide an API that enables you to write asynchronous code. With Kotlin coroutines, you can define aCoroutineScope which helps you to manage when your coroutines should run. Each asynchronous operation runs within a particular scope.

ViewModelScope

You can access the CoroutineScope of a ViewModel through the viewModelScope property of the ViewModel, as shown in the following example:

To have access to this extension, import the following dependency in your build.gradle file:

api 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0-beta01'

Applying viewModelScope to clean architecture

Domain — Functional Use Cases

Take a look at a UseCase abstraction which acts as a contract for all the use cases in my application:

By passing the CoroutineScope to the use case invocation we’re binding the ViewModel to the execution of the use case, hence, killing the activity will cancel any pending jobs avoiding memory leaks.

Either

Quoting Fernando Cejas:

Either<L, R> is referred as a disjoint function, which means that this structure is designed to hold either a Left<T> or Right<T> value but never both. It is a funcional programming monadic type not yet existent in the Kotlin Standard Library.

And quoting Daniel Westheide:

There is nothing in the semantics of the Either<L, R> type that specifies one or the other sub type to represent an error or a success, respectively. In fact, Either is a general-purpose type for use whenever you need to deal with situations where the result can be of one of two possible types.

The Either implementation from Fernando Cejas is on point. The Generic Failure class I use is implemented here.

A “GetFriendsUseCase” in action

GetFriendsUseCase.kt implementation

Pretty straight forward, uses a Repository to retrieve information and it either returns a List of users or a GetFriendsFailure in case something goes wrong.

Presentation layer

The ViewModel

The ViewModel

When the fragment/activity calls loadData() it will make the use case execute and either handle a success or a failure, they all change the state to the appropriate sealed class instance so the observing view layer can change the UI accordingly.

Fragment

The Fragment

The Fragment triggers the ViewModel to execute the use case and change the UI to reflect the results.

The ViewModel and LiveData extensions can be found here

Note

Thanks

If you are interested in more tech related topics, please check my other articles, follow me on Twitter or check my GitHub projects.

Sources

César Ferreira

Written by

Senior Android Developer, more on me @ https://cesarferreira.com