【发布时间】:2021-06-16 16:43:30
【问题描述】:
我正在开发一个带有 recyclerview 列表(数据位于 Room db 中)和谷歌地图的项目。在 googlemap 上,绘制了从 Room db 收集的不同类型的标记,并且在地图上绘制了列表中完成的操作(即更改 Marker.visibility、颜色等),所有这些都非常有效,直到。 ..
用户在列表中执行操作(更新房间数据库),livedata 观察并启动进程(这可能很耗时),我通过调用lifeCycleScope.launchWhenStarted 解决了这个问题,并在其中使用了withContext(Dispatchers.Default)耗时的部分,再次使用withContext(Dispatchers.Main) 将每个更改移植到googleMap。这很好用。
由于withContext(Dispathcers.Default) 继续工作,实际观察者运行到最后,可能会触发新的 livedata observables。
第二个 observable 触发可能会在协程部分完成之前开始,我可能会遇到并发错误。是否有一种“理智”的方式来“停止”withContext(Dispatchers.Default)(某种“waitFor”条件)内的第二次尝试(或所有后续尝试)的处理,并让它们在正在进行的过程完成时开始?
I.E.代码:
myLiveData.observe(viewLifeCycleOwner){myData->
lifeCycleScope.launchWhenStarted{
//do some context main work
withContext(Dispatchers.Default){
//Do some heavy work pt 1
withContext(Dispatchers.Main) {/*Update views*/}
//Do some heavy work pt 2
withContext(Dispatchers.Main) {/*Update views2*/}
}
}
}
【问题讨论】:
-
您是否考虑过使用协程核心库中的互斥锁? kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/…
-
@PietroScarampella 你有什么好的例子说明 Mutex 如何处理对该观察者的后续调用,它们可以优雅地排队吗?
-
...我的意思是:当两个或多个后续尝试时,当互斥锁被解锁时,他们中的谁会做出反应,只有一个,或两者,或者他们以某种方式排队。
-
如果你不关心后续调用的顺序,互斥锁是一个不错的选择,因为它会被第一个请求它的任务锁定。但是,如果顺序对您很重要,那么请使用
actor,actor 是原子的,并且您发送给它的消息将按顺序执行:kotlinlang.org/docs/… -
您可以使用 Flow 和
collectLatest运算符来代替 LiveData,它会在新值到达时立即取消正在进行的操作。
标签: android kotlin concurrency kotlin-coroutines