【问题标题】:Android Kotlin Coroutine used with function parameters acts odd与函数参数一起使用的 Android Kotlin 协程行为奇怪
【发布时间】:2020-06-01 05:35:51
【问题描述】:

我正在使用协程来格式化列表。

这就是它的样子

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 循环有什么我不知道的地方吗?

【问题讨论】:

    标签: android coroutine


    【解决方案1】:

    使您的代码可取消

    为了让 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

    【讨论】:

    • 还有一个问题。这是否意味着即使作业本身已被取消,foreach 块也不会停止?
    • 是的,它不会自动停止。我们必须根据isActive手动关闭它。
    • 谢谢。手动停止循环就可以了。顺便说一句,foreach 块内部的逻辑由繁重的操作组成,例如多次比较每个项目的 Date 值。 Dispatchers.Default 会阻止 UI 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 1970-01-01
    相关资源
    最近更新 更多