关于LiveData全面详解(附事件总线)

LiveData是AndroidJetpack组件中的一种基于观察者模式的数据持有者,具备生命周期感知能力,能确保只向活跃状态的Observer发送数据。文章详细介绍了LiveData的工作原理,包括粘性事件的处理,以及如何使用MutableLiveData、Transformations.map等进行消息分发和数据转换。同时,提出了实现粘性事件分发的流程和普通消息分发的流程,并探讨了如何构建一个支持粘性事件的消息总线。

作者:苏火火

前言

MVVM 架构模式中,ViewModel 是不会持有宿主的信息,业务逻辑在 ViewModels 层中完成,而不是在 Activities 或 Fragments 中。LiveData 在里面担任数据驱动的作用:

以往我们使用 Handler,EventBus,RxjavaBus 进行消息通信,LiveData 也是一个种观察者模式,作用跟 RxJava 类似,是观察数据的类,相比 RxJava,一般配合 Jetpack 组件配合使用。它能够在 Activity、Fragment 和 Service 之中正确的处理生命周期。

一、什么是LiveData

1.介绍

LiveData 组件是 Jetpack 新推出的基于观察者的消息订阅/分发组件,具有宿主(Activity/Fragment)生命周期感知能力。这种感知能力可确保 LiveData 仅分发消息给与活跃状态的观察者,即只有处于活跃状态的观察者才能收到消息。

LiveData 的消息分发机制,是以往 Handler,EventBus,RxjavaBus 无法比拟的,它们不会顾及当前页面是否可见,一股脑的有消息就转发。导致即便应用在后台,页面不可见,还在做一些无用的绘制,计算(微信的消息列表是在可见状态下才会更新列表最新信息的)将有限的资源让给可见的页面使用。

活跃状态:Observer所在宿主处于STARTED,RESUMED状态。

基于生命周期,其实就是在当前宿主 LifecycleOnwer 注册一个 Observer,那么宿主每次生命周期的变化,都会回调给观察者的 onStateChange() 方法,即便是刚刚注册的观察者宿主也会回调 onStateChange() 方法,会有一个状态同步的过程,LiveData 也是利用这个能力,巧妙实现了当宿主销毁的时候,自动移除注册进来的 Observer,从而避免了手动移除的麻烦。更不会造成内存泄漏,这个也是它的核心思想。

2.LiveData的特点

使用 LiveData 具有以下几点优势:

  • 确保界面符合数据状态:LiveData 遵循观察者模式。当底层数据发生变化时,LiveData 会通知 Observer 对象。
  • 不会发生内存泄漏:观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。
  • 不会因 Activity 停止而导致崩溃:如果观察者的生命周期处于非活跃状态(如返回堆栈中的 Activity),它便不会接收任何 LiveData 事件。
  • 不再需要手动处理生命周期:界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
  • 数据始终保持最新状态:如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。
  • 适当的配置更改:如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。
  • 共享资源:您可以使用单例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象。

LiveData不足之处:

  • 粘性事件不支持取消(后面注册的观察者也能接收数据,无法反注册,但有办法解决)。

3.LiveData核心方法

方法名 作用
observe(LifecycleOwner owner, Observer observer) 注册和宿主生命周期关联的观察者, owner当前生命周期的宿主,当宿主销毁了observer能自动解除注册
observeForever(Observer observer) 注册观察者,不会反注册,需自行维护,没有owner无法管理宿主生命周期
setValue(T value) 发送数据,没有活跃的观察者时不分发,只能在主线程
postValue(T value) setValue一样,但是不受线程限制,内部也是通过handelr.post到主线程,最后还是通过setValue来分发的
onActive() 当且仅当有一个活跃的观察者时会触发
onInactive() 不存在活跃的观察者时会触发

二、LiveData的几种用法

1.MutableLiveData

在使用 LiveData 做消息分发的时候,需要使用这个子类,设计的原因是考虑到单一开闭原则,只有拿到 MutableLiveData 才可以发送消息,LiveData 只能接收消息,避免拿到 LiveData 既能发送消息又能接收消息的混乱使用

public class MutableLiveData<T> extends LiveData<T> {
    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

MutableLiveData 仅仅是把上面两个方法从父类的 protect 改为 public 而已,因为在 LiveData 中无法调用 postValue()setValue()。所以我们在使用 LiveData 做消息分发的时候,我们需要使用它的子类 MutableLiveData。

fun mediatorLiveData() {
    val liveData1 = MutableLiveData<String>()
    val liveData2 = MutableLiveData<String>()
    //在创建一个聚合类MediatorLiveData
    val mediatorLiveData = MediatorLiveData<String>()
    //分别把LiveData合并到mediatorLiveData中
    mediatorLiveData.addSource(liveData1, Observer { data ->
        mediatorLiveData.value = data
    })
    mediatorLiveData.addSource(liveData2, Observer { data ->
        mediatorLiveData.value = data
    })

    //数据监听,一旦liveData1或者LiveData2发送了数据,observer便能观察到,以便统一处理更新
    mediatorLiveData.observe(this, Observer { data ->
        LogUtil.e("mediatorLiveData:$data")
    })

    // 模拟发送数据
    liveData1.p
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值