Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit call in Kotlin Coroutines viewModelScope

Recently I've updated my ViewModel to use new viewModelScope. From its implementation, I see that Dispatchers.Main.immediate is set as the default CoroutineDispatcher for viewModelScope.

So when printing the current Thread in viewModelScope.launch it gives Thread[main,5,main]

But here is my question. Although this runs in Main Thread, the following code works for me which performs a network call.

viewModelScope.launch {
    userRepo.login(email, password)
}

Here userRepo.login(email, password) is suspend function, which calls Retrofit suspend function.

So how this works, if my Current Thread is Main Thread?

like image 577
Tiko Avatar asked Apr 14 '20 19:04

Tiko


2 Answers

It works because Retrofit's suspend implementation delegates to Call<T>.enqueue. This means it already executes on its own background executor by default instead of using the caller's Dispatcher.

like image 104
Kiskae Avatar answered Oct 19 '22 07:10

Kiskae


suspend functions are always safe to call from the main thread. But if you are going to do heavy operations like fetch data from server, database, content loader... it is better to use the appropriate dispatcher, for example, Dispatcher.IO.

If you want you can use this dispatcher with the viewmodelScope, and then all the suspends functions runs with this dispatcher.

Now the ViewModel is an Executor (a class that changes the execute from Main to background)

If you are going to change the dispatcher in the ViewModel, a good practice is to inject this Dispatcher by constructor to test the ViewModel.

like image 32
Manuel Mato Avatar answered Oct 19 '22 07:10

Manuel Mato