android - 与函数参数一起使用的 Android Kotlin 协程行为奇怪
问题描述
我正在使用协程来格式化列表。
这是它的样子
val job : Job? = null
private fun formatList(originalList:MutableList<MY_OBJECT>, callback : (MutableList<MY_OBJECT>) -> Unit){
if(job != null && !job?.isCompleted!!){
job?.cancel()
}
job = viewModelScope.launch(Dispatchers.IO) {
originalList.foreach { item ->
//do something with the item.
}
}
}
这个方法可以在运行时多次调用,为了避免它做同样的事情,如果工作还没有完成,我添加了一个取消调用。
问题是,在运行时,foreach 块内的东西会随机产生一些与索引相关的崩溃。
为什么会这样?这是关于协程执行背后的事情吗?或者有什么我对 foreach 循环不了解的地方吗?
解决方案
使您的代码可取消
要使 job.cancel() 正常工作,您需要使协程内的代码可取消。
job = viewModelScope.launch(Dispatchers.IO) {
originalList.foreach { item ->
if(!isActive) return@launch
//do something with the item.
}
if(!isActive) return@launch
// do something
}
这里的行if(!isActive) return@launch
是检查协程是否仍然处于活动状态。在计算密集型代码之前和之后检查isActive
是一种很好的做法。
注意:如果您没有进行任何网络或数据库调用,请始终尝试使用Dispatchers.Default
为计算优化的而不是Dispatchers.IO
.
推荐阅读
- laravel - 如何在 Laravel Query 中使用 CONCAT 函数
- mysql - 如何创建超过当日交易数量和交易限额的客户名单
- javascript - 如何在Vuejs中查看同一数组中的不同键
- android - 改造错误 URL 查询字符串不能通过动态提供的值替换块
- sql-server - SQL Server 存储过程需要未提供的参数
- javascript - 验证值是否正确
- android - React Native 无法在 android 中创建发布版本
- android - 如何在没有剪切和拉伸的情况下设置自定义评分栏的高度和宽度。
- vb.net - 如何在 Visual Basic 中忽略区分大小写?
- c++ - 在我的程序中包含 ntddk.h 和 wdm.h 时出现 100 个错误