首页 > 解决方案 > LiveData 的竞争条件

问题描述

TL;这个问题的博士:

用于和ArrayList的 ViewModel 内部的LiveDataa是否可能具有竞争条件并且需要 using或 a ?前提是 ArrayList 将从回调中获取其值backing property (MutableLiveData)ObserveAddSynchronizedLock

我正在尝试使用Agora Android SDK 设置群组视频通话。我按照这里的文档。问题出callbacks (onUserJoined, onUserOffline)IRtcEngineEventHandler 上

OnUserJoined 回调

mRtcEngine = RtcEngine.create(baseContext, APP_ID, object : IRtcEngineEventHandler() {
override fun onUserJoined(uid: Int, elapsed: Int) {
    // onUserJoined callback is called anytime a new remote user joins the channel
    super.onUserJoined(uid, elapsed)

    // We mute the stream by default so that it doesn't consume unnecessary bandwidth
    mRtcEngine?.muteRemoteVideoStream(uid, true)

    // We are using a lock since uidList is shared and there can be race conditions
    lock.lock()
    try {
        // We are using uidList to keep track of the UIDs of the remote users
        uidList.add(uid)
    } finally {
        lock.unlock()
    }

onUserOffline 回调

override fun onUserOffline(uid: Int, reason: Int) {
    // onUserOffline is called whenever a remote user leaves the channel
    super.onUserOffline(uid, reason)

    // We use toRemove to inform the RecyclerView of the index of item we are removing
    val toRemove: Int

    // We are using a lock since uidList is shared and there can be race conditions
    lock.lock()
    try {
        // We are fetching the index of the item we are about to remove and then remove the item
        toRemove = uidList.indexOf(uid)
        uidList.remove(uid)
    } finally {
        lock.unlock()
    }

这里Lock是用来防止访问uidlist的。当我完全遵循文档时,它对我有用,但是当我尝试使用 a和 a来保存 时,观察者总是返回一个空列表。thread saferace conditionLiveDatabacking property (MutableLiveData)ViewModeluidlistuidlist

我的视图模型

class MainViewModel: ViewModel() {
private val _uidList: MutableLiveData<ArrayList<Int>> = MutableLiveData()
val uidList: LiveData<ArrayList<Int>> get() = _uidList

init {
    _uidList.value = ArrayList<Int>()
}

fun addToUserList(uid: Int) {
    _uidList.value?.add(uid)
    Log.d("adding user ","$uid")
}

fun removeFromUserList(uid: Int) {
    _uidList.value?.remove(_uidList.value!!.indexOf(uid))
}

}

我在addToUserList()里面onUserJoined()removeFromUserList()里面打电话onUserOffline()

请指导我解决这个问题,

谢谢

标签: androidkotlinsynchronizationandroid-livedata

解决方案


你不应该改变存储在 中的值LiveData,你会得到非常奇怪的行为。您必须完全交换价值。

我有点懒,所以我就给你答案。

class MainViewModel: ViewModel() {
private val _uidList: MutableLiveData<List<Int>> = MutableLiveData()
val uidList: LiveData<List<Int>> get() = _uidList

init {
    _uidList.value = emptyList<Int>()
}

fun addToUserList(uid: Int) {
    _uidList.value = (_uidList.value ?: emptyList()) + uid
    Log.d("adding user ","$uid")
}

fun removeFromUserList(uid: Int) {
    val value = _uidList.value?.toMutableList()
    if (value == null) return
    value.remove(value.indexOf(uid))
    _uidList.value = value
}

推荐阅读