繁体   English   中英

将变量传递给 Android 中的 Kotlin 协程

[英]Passing variables to Kotlin Coroutine in Android

我有一个片段、视图模型和数据库。 我从片段中的 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]

您拥有的代码应该可以正常工作,但看起来您在调用deleteDefects时正在做一些顽皮的事情。

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

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

deleteDefects(idList)
idList.clear()

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

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

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)
    }
}

一个适当的解决方法是在调用deleteDefacts(idList)后不修改idList

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

调用者中的线程(函数deleteDefects )不会等到被调用者完成(有时)。 要对其进行测试,请将其包装在runBlocking中。

建议:使用等待或加入。

这篇文章可以帮助弄清楚。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM