android - 如何取消收集协程StateFlow?
问题描述
我从片段中的共享视图模型中收集了流:
private val viewModel: MyViewModel by sharedViewModel()
private fun observeViewModelStateFlowData() {
job = lifecycleScope.launch {
viewModel.stateFlowData.collect {
when (it) {
is ViewStates.Success -> handleSuccess(it.data)
}
}
}
}
在视图模型中:
private val _stateFlowData = MutableStateFlow<ViewStates<Model>>(ViewStates.Idle)
val stateFlowData: StateFlow<ViewStates<Model>> get() = _stateFlowData
但是当我转到下一个片段并再次回到这个片段时,再次收集流。我在片段的 onStop() 生命周期方法中取消了作业:
override fun onStop() {
job?.cancel()
super.onStop()
}
但不能取消并再次收集!!!
即使我离开活动(当视图模型被清除)并再次回到活动时也会发生这种情况!!!
我该怎么做才能防止流量聚集?
解决方案
好吧,您必须对协程有所了解。如果我们只是调用取消,并不意味着协程工作就会停止。如果您正在执行一些相对繁重的计算,例如从多个文件中读取,则没有什么可以自动阻止您的代码运行。
您需要确保您正在实施的所有协程工作都与取消合作,因此您需要定期或在开始任何长时间运行的工作之前检查取消。在处理结果之前尝试添加检查。
job = lifecycleScope.launch {
viewModel.stateFlowData.collect {
ensureActive()
when (it) {
is ViewStates.Success -> handleSuccess(it.data)
}
}
}
}
有关更多信息,请查看这篇文章https://medium.com/androiddevelopers/cancellation-in-coroutines-aa6b90163629
推荐阅读
- android - 单击Listener not working on listview on custom adapter
- django-rest-framework - 从登录用户的请求对象访问装饰器中的用户对象
- css - 是否可以更改 Material-ui 版本 0.18 的 RaisedButton 的选定(或活动)状态的样式?
- c# - WebClient.DownloadDataAsync 正在返回损坏的数据
- javascript - Javascript 日期/时间在带有 Chrome 的 iOS 设备上不起作用
- c - 如何处理负数:在 C 中不使用“/”、“%”和“*”运算符获取商和余数
- mongodb - 在 mongodb 中显示集合的某些元素
- postgresql - 如何在滞后函数中使用别名列
- javascript - bootstrap 手风琴默认在桌面上显示,默认在移动设备上隐藏
- php - Google\Cloud\Storage\StorageObject->downloadAsString() 未捕获错误