Вызов нескольких методов модели просмотра из launchWhenStarted не работает [дубликат]

Этот код вызывает два метода для одной и той же модели просмотра и прослушивает обновления. Но завершается только первый метод, второй не запускает событие.

      private fun initData() {
    lifecycleScope.launchWhenStarted {
        viewModel.incrementCount().collect {
            info { "Count: $it" }
        }

        viewModel.getAllTeams().collect {
            when (it) {
                is State.Success -> {
                    info { "Got teams with size: ${it.result}.size" }
                }
                is State.Error -> {
                    info { "Error getting teams: ${it.message}" }
                }
                State.Loading -> {
                    info { "Loading all teams" }
                }
            }
        }
    }
}

ViewModel

      class DashboardViewModel : ViewModel(), com.droid.common.Logger {

fun incrementCount(): MutableStateFlow<Int> {
    val countState = MutableStateFlow(0)

    viewModelScope.launch {
        repeat(5) {
            countState.value = (it)
            delay(1000)
        }
    }

    return countState
}

fun getAllTeams(): MutableStateFlow<State> {
    val state = MutableStateFlow<State>(State.None)

    state.value = State.Loading

    viewModelScope.launch {
        try {
            val allTeams = FootballAPIClient.apiService.getAllTeams()
            state.value = State.Success(allTeams)
        } catch (exception: Exception) {
            error { "Error getting all teams: ${exception.message}" }
            state.value = State.Error(exception.message.toString())
        }
    }

    return state
}

Однако вызов их с отдельным lifecycleScope работает

      private fun initData() {
    lifecycleScope.launchWhenStarted {
        viewModel.incrementCount().collect {
            info { "Count: $it" }
        }
    }

    lifecycleScope.launchWhenStarted {
        viewModel.getAllTeams().collect {
            when (it) {
                is State.Success -> {
                    info { "Got teams with size: ${it.result}.size" }
                }
                is State.Error -> {
                    info { "Error getting teams: ${it.message}" }
                }
                State.Loading -> {
                    info { "Loading all teams" }
                }
            }
        }
    }
}

Кажется, я не могу понять этого поведения, кто-нибудь знает почему?

1 ответ

Вам потребуются разные сопрограммы, так как collect() это функция приостановки, которая приостанавливается до тех пор, пока вы Flow прекращается.

Проблема с launchWhenStarted заключается в том, что пока ваши недавно выпущенные элементы не будут обработаны, ваш производитель все равно будет работать в фоновом режиме.

В настоящее время рекомендуемый способ сбора нескольких потоков:

      lifecycleScope.launch {
    lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
        launch {
          viewModel.incrementCount().collect { ... }   
        }
    
        launch {
            viewModel.getAllTeams().collect { ... }
        }
    }
}
Другие вопросы по тегам