Kotlin Coroutines MVVM Retrofit UnitTestCases — Part1

ChandraSaiMohan bhupathi
3 min readMay 3, 2020

--

What are Coroutines ?

Difference b/w Coroutines and Threads :

Coroutines and the threads both do multitasking. But the difference is that threads are managed by the OS and coroutines by the users as it can execute a few lines of function by taking advantage of the cooperation.

Definition of Coroutines as per official documentation:

Coroutine are light-weight threads. Like threads, coroutines can run in parallel, wait for each other and communicate. The biggest difference is that coroutines are very cheap, almost free. we can create thousands of them, and pay very little in terms of performance. True threads, on the other hand, are expensive to start and keep around. A thousand threads can be a serious challenge for a modern machine.

Standard Way of Executing Background operations:

UseCase:
• Fetch Info from the server.
• Display the Info in the UI.

(1) Using Callback:
run the fetchInfo in the background thread and we pass the result with the callback.
fun fetchAndShowInfo() {
fetchInfo { info ->
displayInfo(info)
}
}

(2) Using RxJava: Reactive world approach. This way we can get rid of the nested callback.
fetchInfo()
.subscribeOn(Schedulers.io())
.observerOn(AndroidSchedulers.mainThread())
.subscribe { info ->
displayInfo(info)
}

(3)Using Coroutines:

suspend fun fetchAndDisplayInfo() {
val info = fetchInfo() // fetch on IO thread
displayInfo(info) // results on UI thread
}

The above looks synchronous but its Asynchronous

Coroutine Terminology:

Dispatchers:

Dispatchers helps coroutines in deciding the thread on which the work has to be done. There are majorly three types of Dispatchers which are as IO, Default, and Main. IO dispatcher is used to do the network and disk related work. Default is used to do the CPU intensive work. Main is the UI thread of Android. In order to use these, we need to wrap the work under the async function. Async function looks like below.

suspend fun fetchInfo(): Info {
return GlobalScope.async(Dispatchers.IO) {
// make network call and return results
}.await()
}

Suspend functions:

Functions that can be run in an coroutine are called suspend functions.
Normal functions will not run. These functions should be appended with “Suspend” keyword.

These are the functions that can be started, paused and resumed.

Functions that can be run in coroutine. Fncns that can be suspended.

Example of Activity:

Example:

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

GlobalScope.launch(Dispatchers.Main) {
val info = fetchInfo() // fetch on IO thread
displayInfo(info) // back on UI thread
}

}

Different ways of starting a coroutine:

(1) Launch
(2) Async

Launch vs Async in Kotlin Coroutines:

The difference is that the launch{} does not return anything and the async{}returns an instance of Deferred<T>, which has an await()function that returns the result of the coroutine

Example of Launch:
GlobalScope.launch(Dispatchers.IO) {
fetchResultsAndSaveInDB() // do on IO thread
}

Example of async:
GlobalScope.launch(Dispatchers.Main) {
val info1 = async(Dispatchers.IO) { fetchFirstInfo() }
val info2 = async(Dispatchers.IO) { fetchSecondInfo() }
showInformation(info1.await(), info2.await()) // back on UI thread
}

fun fetchFirstInfo(): Info {
// make network call
// return info
}

fun fetchSecondInfo(): Info {
// make network call
// return info
}

No need to make the above functions as suspend as we are not calling any other suspend function from them.

Scopes in Kotlin Coroutines:

Scopes in Kotlin Coroutines are very useful as we need to cancel the background task as soon as the activity is destroyed.

Scopes Create and run coroutines. Provides lifecycle events like pausing and running coroutines.

Using Scopes in Android Architecture Components:

As part of KTX extensions the below are the coroutine scopes provided as part of Android Architecture components:

ViewModelScope:

A ViewModelScope is defined for each ViewModel in your app. Any coroutine launched in this scope is automatically canceled if the ViewModel is cleared. Coroutines are useful here for when you have work that needs to be done only if the ViewModel is active.

Advantage: No need to manually handle Coroutine scopes .ViewModelScope does all these for us.

LifecycleScope:A LifecycleScope is defined for each Lifecycle object. Any coroutine launched in this scope is canceled when the Lifecycle is destroyed.

--

--

No responses yet