Why does viewModelScope.launch run on the main thread by default Why does viewModelScope.launch run on the main thread by default multithreading multithreading

Why does viewModelScope.launch run on the main thread by default


ViewModelScope.launch { } runs on the main thread, but also gives you the option to run other dispatchers, so you can have UI & Background operations running synchronously.

For you example:

fun thisWillRunOnMainThread() {    viewModelScope.launch {         //below code will run on UI thread.        showLoadingOnUI()        //using withContext() you can run a block of code on different dispatcher        val result = novel.id = withContext(Dispatchers.IO) {            withsomeRepository.someWork()        }        //The below code waits until the above block is executed and the result is set.        liveData.value = result        finishLoadingOnUI()    }}

For more reference, I would say there are some neat articles that will help you understand this concept.

Medium link that explains it really neat.


So my second question is, is this the way to go ?

I would expect two things to be different in your current approach.

1.) First step would be to define the scheduler of the background operation via withContext.

class SomeRepository {    suspend fun doWork(): SomeResult = withContext(Dispatchers.IO) {        ...    }}

This way, the operation itself runs on a background thread, but you didn't force your original scope to be "off-thread".

2.) Jetpack Lifecycle KTX provides the liveData { coroutine builder so that you don't have to postValue to it manually.

val liveData: LiveData<SomeResult> = liveData {    emit(someRepository.someWork())}

Which in a ViewModel, you would use like so:

val liveData: LiveData<SomeResult> = liveData(context = viewModelScope.coroutineContext) {    withContext(Dispatchers.IO) {        emit(someRepository.someWork())    }}

And now you can automatically trigger data-loading via observing, and not having to manually invoke viewModelScope.launch {}.