作者:苏火火
前言
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

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

被折叠的 条评论
为什么被折叠?



