Mena
Mena

Reputation: 3385

How to make a flow run on a different thread than the one used for collection?

I have a flow that does CPU intensive work as shown below:

fun doWork():Flow<MyResult> = 
 flow{
  for(i in 1..100){
   //calculate()
   }  
   emit(MyResult())
 }

I collect from it inside a Fragment as shown below:

 viewLifecycleOwner.lifecycleScope.launchWhenCreated {
            launch {
                viewModel.doWork().collect {
                    val result = it ?: return@collect
                    // Preview result
                }
            }
        }

But, since I am collecting using the main thread, the flow body runs on the main thread which is not the best thing to do.

How can I make the flow execute on a different thread?

Upvotes: 0

Views: 1816

Answers (1)

Mena
Mena

Reputation: 3385

In case you intend to do heavy calculations inside a flow it is recommended to move it to the default dispatcher like so,

  flow{
     //CPU intensive work
  }.flowOn(your chosen dispatcher)

Libraries like the Room database and retrofit for networking handle the correct threading under the hood for you, so you do not have to worry about using .flowOn

Using withContext() inside a flow will not work for you.

This link is also very useful if you want to know more about asynchronous Flow.

Upvotes: 2

Related Questions