问题描述
这段代码在同一个视图模型上调用两个方法并监听更新。但是只有第一个方法完成,第二个没有事件触发。
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" }
}
}
}
}
}
我似乎无法理解这种行为,有人知道为什么吗?
解决方法
您将需要不同的协程,因为 collect()
是一个挂起函数,它会挂起直到您的 Flow
终止。
launchWhenStarted
的问题在于,虽然您新发出的项目不会被处理,但您的生产者仍会在后台运行。
对于收集多个流,目前推荐的方法是:
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
viewModel.incrementCount().collect { ... }
}
launch {
viewModel.getAllTeams().collect { ... }
}
}
}