Parallel Multiple Network Calls Using Kotlin Coroutines

Parallel Multiple Network Calls Using Kotlin Coroutines

In this tutorial, we are going to learn how to make the multiple network calls in parallel using Kotlin Coroutines. We will learn to write the code inside the ViewModel with Kotlin Coroutines and LiveData that follows a basic MVVM Architecture. This tutorial will also help you in doing any type of background tasks in parallel using Kotlin Coroutines.

I will be using this project for the implementation part. If you have not gone through the project, you should go through and then come back. The project follows a basic MVVM Architecture for simplicity. You can find the complete code for the implementation mentioned in this blog in the project itself.

We will take the example of ParallelNetworkCallsViewModel which is present in the project.

Basically, this ParallelNetworkCallsViewModel is a ViewModel that is associated with ParallelNetworkCallsActivity which triggers the ViewModel to fetch the list of users to render into the UI. The ParallelNetworkCallsViewModel, then asks the data layer for the list of users using the ApiHelper. The ViewModel makes the two networks in parallel which are as getUsers and getMoreUsers. As you can see below, the ViewModel uses the Kotlin Coroutines and LiveData.

class ParallelNetworkCallsViewModel(
    private val apiHelper: ApiHelper,
    private val dbHelper: DatabaseHelper
) : ViewModel() {

    private val users = MutableLiveData<Resource<List<ApiUser>>>()

    init {
        fetchUsers()
    }

    private fun fetchUsers() {
        viewModelScope.launch {
            users.postValue(Resource.loading(null))
            try {
                // coroutineScope is needed, else in case of any network error, it will crash
                coroutineScope {
                    val usersFromApiDeferred = async { apiHelper.getUsers() }
                    val moreUsersFromApiDeferred = async { apiHelper.getMoreUsers() }

                    val usersFromApi = usersFromApiDeferred.await()
                    val moreUsersFromApi = moreUsersFromApiDeferred.await()

                    val allUsersFromApi = mutableListOf<ApiUser>()
                    allUsersFromApi.addAll(usersFromApi)
                    allUsersFromApi.addAll(moreUsersFromApi)

                    users.postValue(Resource.success(allUsersFromApi))
                }
            } catch (e: Exception) {
                users.postValue(Resource.error("Something Went Wrong", null))
            }
        }
    }

    fun getUsers(): LiveData<Resource<List<ApiUser>>> {
        return users
    }

}

The above code makes both the network calls in parallel.

Now, let's try to understand how it is doing the two background tasks in parallel using Kotlin Coroutines.

Here if you notice, we have used the async{} which returns an instance of Deferred<T>, which has an await() function that returns the result of the coroutine like we have future in Java in which we do future.get() to the get the result.

Here, it makes both the network calls in parallel and await for the results.

The key point here is to use async to do the network calls in parallel.

Learn more about async from here.

Similarly, we can do any type of background tasks in parallel using Kotlin Coroutines.

Let's take another example.

Suppose we have two functions as below:

  • doLongRunningTaskOne()
  • doLongRunningTaskTwo()
suspend fun doLongRunningTaskOne(): Int {
    // your code for doing a long running task
    return 0
}

suspend fun doLongRunningTaskTwo(): Int {
    // your code for doing a long running task
    return 0
}

And then, we can run the two tasks in parallel using Kotlin Coroutines like below:

fun startLongRunningTaskInParallel() {
    viewModelScope.launch {
        val resultOneDeferred = async { doLongRunningTaskOne() }
        val resultTwoDeferred = async { doLongRunningTaskTwo() }
        val combinedResult = resultOneDeferred.await() + resultTwoDeferred.await()
    }
}

This way, we are able to run two tasks in parallel.

You can find the end to end implementation in this project.

That's it for now.

Also, Let’s become friends on Twitter, Linkedin, Github, Quora, and Facebook.