class CommunityViewModel : ViewModel() 可信数据源

博客讲述了在Android开发中,由于PostState实例在多个线程中被并发修改导致的安全问题。作者提出了Copy-On-Write(COW)策略,通过在修改数据时复制原有数据来确保线程安全。同时,展示了如何修改代码以应用COW原则,避免直接修改LiveData的值,从而消除并发问题。
摘要由CSDN通过智能技术生成

这样写还是要出事,当进入社区时,会根据用户身份展示不同样式的发帖按钮。但在发帖的逻辑中是通过新建 PostState 实例来更新状态的,这样就会丢失原有按钮样式,所以得由上次状态生成新状态

class CommunityViewModel : ViewModel() {
    private val _postStateLiveData = MutableLiveData<PostState>()
    val postStateLiveData: LiveData<PostState> = _postStateLiveData
    
    fun post(){
        // 获取当前状态
        val currentState = _postStateLiveData.value
        // 更改当前状态值
        _postStateLiveData.value = currentState.apply {
            clickable = false, 
            loading = true, 
            text = "发送中..."
        }
        viewModelScope.launch(Dispatchers.IO) {
            // 获取当前状态并修改之
            val currentState = _postStateLiveData.value
            val response = api.post()
            if(response.isFailed){
                _postStateLiveData.postValue(currentState.apply { poorNetwork = true })
            } else {
                when(response.code) {
                    CODE_BAD_WORD -> _postStateLiveData.postValue(
                        currentState.apply { badWord = "敏感词" }
                    )
                    else -> _postStateLiveData.postValue(
                        currentState.apply {success = true }
                    )
                }
            }
        }
    }
}
复制代码

这样写接着出事。。。

现在_postStateLiveData.value成了“共享变量”,会存在多线程并发读写,存在线程安全问题。

解决办法是COW,即 copy on write,在写变量的时候先拷贝源变量,然后对副本写。

关于 COW 的详细分析可以点击面试题 | 有用过并发容器吗?有!比如网络请求埋点

为了禁止变量的直接写操作,遂把唯一数据源的所有字段都定义成 val:

data class PostState(
    val clickable: Boolean = true,
    val backgroundColor: Int = 0xFF00FF, 
    val text: String = "发帖", 
    val loading: Boolean = false,
    val poorNetwork: Boolean = "", 
    val badWord: String = "",
    val success: Boolean = false
)


作者:唐子玄
链接:https://juejin.cn/post/7087717477246369805
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值