Android Flow error ReceiveChannel.consumeAsFlow can be collected just once

Viewed 523

I'm having a problem with an Android Flow. The fragment 1 collects some information from a flow. The subscription for the flow happens in the onResume method, like that

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.consumeAsFlow    
 private var commandJob: Job? = null

override fun onResume(){
       super.onResume()
commandJob = lifecycleScope.launch(Dispatchers.Main) {
            viewModel.commandKN.collect { processCommand(it) }
        }
}

and then in the onPause:

 override fun onPause() {
        super.onPause()
        commandJob?.cancel()
    }

In theory, this is working well. When the fragment is started, then the job is initialized, and starts receiving information from the viewModel. When the user navigates to another fragment2 or activity2, the job is cancelled. If the user navigates back from the activity2 or fragment2, to fragment1 then the job starts collecting information again from the flow.

The problem happens if the user navigates forward and backward very fast. Although the onPause method from the fragment1 was executed (checked with log messages), and the corresponding commandJob.cancel was executed, the next time the onResume method is called, it seems that the command.cancel command has not finished yet, and the following exception is thrown:

java.lang.IllegalStateException: ReceiveChannel.consumeAsFlow can be collected just once
        at kotlinx.coroutines.flow.ChannelAsFlow.markConsumed(Channels.kt:130)

If the user navigates forward and backward with a normal speed, then all works as expected.

I'm doing something wrong here? Thanks

0 Answers
Related