Android How to execute flow.map() in viewModel on Dispatchers.Default

Viewed 1018

I am developing an Android application, using the MVVM design pattern.

So, I have a repository that exposes a flow<T> to a ViewModel. The ViewModel then converts the flow<T> to LiveData<T> using asLiveData() as per the code below.

repository.getFlow().map {
    // I will do some long running work here
}.asLiveData()

As you can see, I will do some long-running work in map { }. So I want to execute the code inside map { } in Dispatchers.Default thread.

From my research, I can do with flowOn(Dispatchers.Default) or asLiveData(viewmodelScope.coroutineContext + Dispatchers.Default) as per the code below.

  1. map{} with flowOn(Dispatchers.Default)
repository.getFlow().map {
   // I will do some long running work here
}.flowOn(Dispatchers.Default).asLiveData()
  1. map{} with asLiveData(viewmodelScope.coroutineContext + Dispatchers.Default)
repository.getFlow().map {
   // I will do some long running work here
}.asLiveData(viewmodelScope.coroutineContext + Dispatchers.Default)

I'd like to understand better about coroutine context, scope and flowOn(). So my questions are as follows

1-1. Does asLiveData(viewmodelScope.coroutineContext + Dispatchers.Default) mean that asLiveData() function will execute in a new coroutine with Dispatchers.Default in viewmodelScope?

1-2. So, then the map {} function executes in the new coroutine with Dispatchers.Default because flow's intermediate operator executes in consumer's coroutine?

  1. I also read flowOn(Dispatchers.Default) executes the upstream flow in the CoroutineContext defined in flowOn() function, which mean that the map{} will execute in Dispatchers.Default thread. Is it fine to use flowOn() in viewmodel with asLiveData()?

Thank you guys

1 Answers
  1. Not sure I understand the question, but basically it means that the flow collection will happen on the passed coroutine context (viewmodelScope + bg thread) and the value will be propagated to the livedata from the bg thread. But the propagation (an emit() call) will always switch to the Main dispatcher.
  2. Yes, when you use flowOn(), all the upstream operators (your map) are run on the defined dispatcher until new flowOn() operator appears. And yes, it is ok to use it with combination with asLiveData().

These two options should be equivalent; I would aim for the clarity, which seems to be better covered with the flowOn() usage.

Related