【问题标题】:Calling multiple viewmodel methods from launchWhenStarted does not work [duplicate]从launchWhenStarted调用多个视图模型方法不起作用[重复]
【发布时间】:2021-06-06 16:55:53
【问题描述】:

此代码在同一视图模型上调用两个方法并侦听更新。但是只有第一个方法完成,第二个没有事件触发。

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" }
                }
            }
        }
    }
}

视图模型

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
}

但是,使用单独的生命周期范围调用它们是可行的

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" }
                }
            }
        }
    }
}

我似乎无法理解这种行为,有人知道为什么吗?

【问题讨论】:

    标签: android kotlin viewmodel kotlin-stateflow


    【解决方案1】:

    您将需要不同的协程,因为collect() 是一个暂停函数,它会暂停直到您的Flow 终止。

    launchWhenStarted 的问题在于,虽然您新发出的项目不会被处理,但您的生产者仍将在后台运行。

    对于收集多个流,目前推荐的方法是:

    lifecycleScope.launch {
        lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
            launch {
              viewModel.incrementCount().collect { ... }   
            }
        
            launch {
                viewModel.getAllTeams().collect { ... }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-08-14
      • 1970-01-01
      • 2015-11-01
      • 2018-12-17
      • 1970-01-01
      • 2012-02-01
      • 2012-06-19
      • 1970-01-01
      • 2013-10-20
      相关资源
      最近更新 更多