首页 > 解决方案 > 在 Android 中将变量传递给 Kotlin 协程

问题描述

我有一个片段、视图模型和数据库。我从片段中的 viewModel 中调用此方法,该片段通过 id 列表从数据库中删除数据。

    fun deleteDefects(idList: List<Long>) {
        Log.d("RoundViewModel", idList.toString())
        viewModelScope.launch(Dispatchers.IO) {
            Log.d("RoundViewModel", idList.toString())
            ddb.dao().delAddedDefect(idList)
        }
    }

它有效.. 有时,10 次中有 2 到 3 次会删除数据。有时启动中的 idList 是空的。

2020-06-26 18:40:44.461 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [259, 260]
2020-06-26 18:40:44.464 18524-18555/ru.debaser.projects.inspectionsheet D/RoundViewModel: []
2020-06-26 18:40:47.453 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [264, 267]
2020-06-26 18:40:47.457 18524-18555/ru.debaser.projects.inspectionsheet D/RoundViewModel: []
2020-06-26 18:40:50.838 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [276, 267]
2020-06-26 18:40:50.841 18524-18555/ru.debaser.projects.inspectionsheet D/RoundViewModel: []
2020-06-26 18:40:53.896 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [276, 267, 264]
2020-06-26 18:40:53.899 18524-18555/ru.debaser.projects.inspectionsheet D/RoundViewModel: []
2020-06-26 18:40:56.947 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [259, 260, 264]
2020-06-26 18:40:56.950 18524-18555/ru.debaser.projects.inspectionsheet D/RoundViewModel: []
2020-06-26 18:41:00.023 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [264, 265, 267]
2020-06-26 18:41:00.027 18524-18554/ru.debaser.projects.inspectionsheet D/RoundViewModel: []
2020-06-26 18:41:02.731 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [264, 265]
2020-06-26 18:41:02.733 18524-18554/ru.debaser.projects.inspectionsheet D/RoundViewModel: []
2020-06-26 18:41:08.200 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [277, 267]
2020-06-26 18:41:08.201 18524-18554/ru.debaser.projects.inspectionsheet D/RoundViewModel: []
2020-06-26 18:41:11.694 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [264, 259]
2020-06-26 18:41:11.695 18524-18554/ru.debaser.projects.inspectionsheet D/RoundViewModel: [264, 259]
2020-06-26 18:41:19.528 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [265, 267]
2020-06-26 18:41:19.530 18524-18591/ru.debaser.projects.inspectionsheet D/RoundViewModel: []
2020-06-26 18:41:23.780 18524-18524/ru.debaser.projects.inspectionsheet D/RoundViewModel: [276, 267]
2020-06-26 18:41:23.782 18524-18556/ru.debaser.projects.inspectionsheet D/RoundViewModel: [276, 267]

标签: androidkotlinkotlin-coroutines

解决方案


您拥有的代码应该可以正常工作,但看起来您在调用deleteDefects.

List<...>是一个只读接口,它不保证不变性。idList我想你在将它传递给函数之后正在修改它。像这样的东西...

val idList = mutableListOf<Long>()
idList.add(50)
idList.add(20)

deleteDefects(idList)
idList.clear()

这是一个竞赛条件!由于在 中引入了并发性,因此在传入后deleteDefects您不应该触摸idList......永远。除非你使用锁或类似的东西。

一个快速的解决方法是制作一个防御性副本,就像这样。

fun deleteDefects(idListTmp: List<Long>) {
    val idList = idListTmp.toList() // Safe!
    Log.d("RoundViewModel", idList.toString())
    viewModelScope.launch(Dispatchers.IO) {
        Log.d("RoundViewModel", idList.toString())
        ddb.dao().delAddedDefect(idList)
    }
}

一个适当的解决方法是idList在调用deleteDefacts(idList).

另一个适当的解决方法可能是只做deleteDefacts(idList.toList()).


推荐阅读