В области жизненного цикла с двумя наблюдателями потока состояний работает только первый

#android #kotlin #kotlin-coroutines #android-lifecycle #kotlin-stateflow

Вопрос:

Мне кажется, что я чего-то не совсем понимаю. Не могли бы вы объяснить мне, пожалуйста, почему, когда я использую этот пример, для меня работает только первый сбор.

     lifecycleScope.launch {
        viewModel.test1.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect {
            Log.i("Log_tag", it)
        }
        viewModel.test2.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect {
            Log.i("Log_tag", it)
        }
    }
 

или если я назову их так:

   lifecycleScope.launch {
        viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED){
            viewModel.test1.collect {
                Log.i("Log_tag", it)
            }
            viewModel.test2.collect {
                Log.i("Log_tag", it)
            }
        }
    }
 

Но если я вызову их в разных сопрограммах, то они будут работать и так, и так, как здесь:

   lifecycleScope.launch {
        viewModel.test1.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect {
            Log.i("Log_tag", it)
        }

    }

    lifecycleScope.launch {
        viewModel.test2.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect {
            Log.i("Log_tag", it)
        }
    }
 

Модель представления:

 class ForecastViewModel : ViewModel() {
private val _test1 = MutableStateFlow("")
private val _test2 = MutableStateFlow("")
val test1 = _test1.asStateFlow()
val test2 = _test2.asStateFlow()

fun getTest() {
    viewModelScope.launch {
        _test1.value = "test1"
        _test2.value = "test2"

    }
}
 

Ответ №1:

Сбор a StateFlow никогда не заканчивается, потому что потоки состояний не заканчиваются.

Это вполне ожидаемо. Запуск параллельных коллекторов-это правильно.

(Интересно, могли бы они «переопределить» StateFlow.collect тип возвращаемого Nothing значения, чтобы сделать это более понятным.)