LiveData 的正确使用姿势以及反模式

本文原始发表于:https://juejin.cn/post/6955726530911666190

借助 LiveData 的能力,在 View(Activity 或者 Fragment)和 ViewModel 之间,使用 LiveData 通信,当 LiveData 发生变化的时候,订阅了该 LiveData 的 View 能够收到通知以便做出相应的更新 UI 逻辑。

这种特性对于那种需要持续监听数据变化,然后实时做出 UI 响应的场景十分有用且便利。

Untitled.png

然而,这里有个细节需要注意:View 在 observes LiveData 的那一刻,便能收到一次通知,拿到当前 LiveData 的值。换句话说,我们可以在监听 LiveData 的时候,拿到监听之前设置给 LiveData 的值 —— 我们称之为粘性消息

但是有时候,我们并不希望在监听的时候拿到「上一次的值」。比如我们实现收款到账提醒的功能,我们希望每次有新收到账的时候,发送一个到账通知的提醒,假设我们监听之前,已经有到账记录了,这时候如果我才开始监听,然后提醒我有新的到账(实际上是上一次的到账),这就有问题了。

LiveData 的这种特性,这并不是一个 Bug,LiveData 设计之初并不是给我们用来当成 EventBus 使用的,而是用于监听「状态」的,此处引用官博的原文

Instead of trying to solve this with libraries or extensions to the Architecture Components, it should be faced as a design problem.

如何理解状态(state)和事件(event)?

简单理解:「状态」可以持续一段时间,而「事件」指某一刻发生的事情

拿一个简单的例子举例:开灯和关灯

Untitled 1.png

  • 关灯和开灯可以理解为是两次事件的发生,而灯是亮的和灯是灭的则是两种状态;
  • 灯亮之后可以获取灯的状态(状态一直在持续),但无法知道是什么时候开灯的(事件是之前发生的,转瞬即逝)
  • 事件的触发可以让状态发生转换

而 LiveData 的特性「监听时能够接收到监听之前已经改变的状态」正是为了「状态」而设计的。因此,并不是所有场景下都适合使用 LiveData,当我们所要监听的数据是符合「状态」特性,而是不是「事件」特性的时候,才是最适合使用 LiveData 的场景

LiveData 常见的几种错误使用姿势

前文之所以花费这么大篇幅介绍 LiveData 的「粘性消息」特性,一是为了让大家对 LiveData 有更深一步的认识,了解其设计之初的目的才知道什么时候该用,什么时候不该用,二是因为如果我们不了解这个特性,很容易引发问题。下面分别介绍几种常见错误使用方式:

case 1:数据是「事件」类型的

以「收款到账提醒举例」

class MvvmViewModel : ViewModel() {
   

    private val _billLiveData = MutableLiveData<String>()

    val billLiveData: LiveData<String>
        get() = _billLiveData

    fun pay(msg: String) {
   
        _billLiveData.value = msg
    }
}
class MvvmActivity : AppCompatActivity() {
   
    private val viewModel by viewModels
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值