本文主要从源码角度介绍架构组件LiveData的实现原理,默认读者已经熟悉LiveData的基本使用。
观察者模式与发布-订阅模式
之前一直没有特别关注过观察者模式与发布-订阅模式的区别,刚好借此机会去了解了一下。简单来说,两者的核心区别是:
在观察者模式的实现中,观察者(订阅者)是由发布者来维护的,也就是说,发布者是可以感知到观察者的。
但是在发布-订阅模式中,会有一个专门的中介来维护订阅者,发布者与订阅者是无法直接交互的,它们是无法感知另一方的存在的。
具体的细节可以参考这篇文章:观察者模式 vs 发布-订阅模式
功能与使用场景
功能
- 可以包装数据,使之可被观察,达到响应式的效果。
- 与页面的生命周期是绑定的,防止内存泄露。
- 有类似RxJava中运算符的实现,数据处理更灵活。
- …
使用场景
多数情况是搭配ViewModel与Lifecycle组件一起使用,使ViewModel具有响应式的效果。
整体架构图
整体采用了观察者模式,核心的类结构图如下:

简单介绍下其中的关键类:
- 抽象类LiveData:架构组件的核心类,代表着可被观察的数据本身,是观察者模式中的发布者,负责被观察数据的维护、观察者的维护以及数据变化后的消息分发。
- Observer接口:代表着观察者,只有一个最简单的 onChanged()方法用于接收变化消息。
- 抽象类ObserverWrapper:顾名思义,Observer的Wrapper,扩展了Observer的功能,使之不仅仅是接收消息那么简单,例如其具体实现LifecycleBoundObserver就赋予了Observer与Lifecycle组件并用的功能。
源码分析
LiveData的源码不多,具体如下
观察者模式在LiveData中如何实现
观察者模式主要涉及观察者注册、观察者维护、消息发送三个部分。
1、先来看看观察者的注册
以LiveData的observe()/observeForever()方法为入口,这里以observe()为例,两者的区别后面再介绍。
1 | public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) { |
可以发现注册的过程就是将Observer与ObserverWrapper放入map中维护。
2、如何移除观察者
移除观察者与注册观察者类似,如果Observer是有生命周期的,那就会根据Observer的生命周期变化自动移除,具体实现看LifecycleBoundObserver.onStateChanged()
1 | class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { |
如果Observer没有生命周期,那么就需要外部调用LiveData的removeObserver()完成移除操作。
3、如何向观察者发送数据变化的通知
数据的变化以LiveData.setValue()为入口:
1 | // 被观察的数据,值只能通过setValue改变。 |
前面提到如果Observer在恢复活跃后会收到最近的一次变化,其具体实现在ObserverWrapper的activeStateChanged()中,即恢复活跃后会调用activeStateChanged,然后调用dispatchingValue(),代码比较简单,这里就不再贴出来了。
Transformations如何实现LiveData转换
LiveData还可以做到类似RxJava中运算符的一些功能,具体实现方式如下。
以map为例,实现的关键在于类MediatorLiveData,它本身就是一个LiveData,并且它持有另外一个LiveData,所以它既是一个观察者,又是一个发布者。
1 | public class MediatorLiveData<T> extends MutableLiveData<T> { |
接着再看Transformations的map的实现
1 |
|
总结上面的代码就是,MediatorLiveData中的Observer监听原始LiveData的变化,当其变化后MediatorLiveData中的Observer就将Transformations提供的func作用于变化后的数据,然后再将这个数据通过MediatorLiveData中的LiveData通知到外部。