LiveData源码解析

LiveData

使用最新的 androidx 的源码。
前言 LiveData 是 Android Architecture Component 中重要的组成部分。
官网上的介绍如下:
LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.
LiveData是一个可观察的数据持有者类。与常规observable不同,LiveData是生命周期感知的,这意味着它能感知其他组件的生命周期,例如Activity,Fragment或Service。 此感知确保LiveData仅更新处于活动生命周期状态的应用程序组件。
综上,LiveData 采用观察者订阅者模式设计,最大的特点是具备生命周期感知能力,它不会因为 View 的生命周期问题引起内存泄漏。
官方文档地址:
https://developer.android.com/topic/libraries/architecture/livedata
LiveData 的基本用法 初始化:
private MutableLiveData mLiveData = https://www.it610.com/article/new MutableLiveData<>();

发送事件:
//ui线程 mLiveData.setValue("hello world"); //子线程 mLiveData.postValue("hello world");

在 View 中接收:
mLiveData.observe(this, text -> {});

LiveData 源码结构 LiveData源码解析
文章图片
LiveData类结构.png 重要的变量
  • mVersion 和 mLastVersion
mVersion mLastVersion
初始值 START_VERSION = -1 START_VERSION = -1
归属类 LiveData ObserverWrapper(抽象内部类)
赋值 setValue/postValue()中 +1 Observer调用onChange()之前将mVersion赋值
作用 mVersion>mLastVersion 才执行 onChange()
  • mObservers
private SafeIterableMap, ObserverWrapper> mObservers =new SafeIterableMap<>();

它是一个以 Observer 为 key 来进行复用 map,ObserverWrapper 类根据类名即可知,它对 Observer 进行扩充。如果在 Activity 中调用 observe() 方法,将 LifecycleOwner 作为key存入map中。
LiveData内部类
LiveData内部类 ObserverWrapper LifecycleBoundObserver AlwaysActiveObserver
抽象和实现类 abstract ObserverWrapper的实现类 ObserverWrapper的实现类
解释 扩充Observer的功能 带生命周期 不带生命周期
shouldBeActive() abstract 当前Owner至少是STARTED才为true return true
onStateChanged() 如果Owner为DESTROYED=>return; 一直执行
重要方法
  • setValue/postValue()
setValue(T value) postValue(T value)
线程 main thread 无限制
功能 dispatchingValue(),分发事件通知Observer 将Runnable抛到主线程,在 Runnable 中调用setValue()
同时调用 先执行(setValue在postvalue后面也是一样) 后执行
调用多次 发送每一条value 只会发送最后一次value
  • observe/observeForever()
observe() observeForever()
生命周期 生命周期感知,active/inActive 无生命周期感知,always active
存入map 将参数observer放入map(mObservers) 将参数observer放入map(mObservers)
不同的内部类 使用LifecycleBoundObserver 使用AlwaysActiveObserver
执行顺序 等待active,owner.getLifecycle().addObserver(wrapper); 立即分发事件(activeStateChanged(true))
是否解注册 不需要手动remove 防止内存泄漏,需要手动 removeObserver()
  • ObserverWrapper#activeStateChanged(boolean newActive)
    void activeStateChanged(boolean newActive) { if (newActive == mActive) { return; } mActive = newActive; boolean wasInactive = LiveData.this.mActiveCount == 0; LiveData.this.mActiveCount += mActive ? 1 : -1; // 如果现在第一次新增活跃的观察者,那么回调 onActive ,onActive 是个空方法 if (wasInactive && mActive) { onActive(); } // 如果现在没有活跃的观察者了,那么回调 onInactive ,onInactive 是个空方法 if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive(); } if (mActive) { // 向观察者发送 LiveData 的值 dispatchingValue(this); } }

  • LiveData#considerNotify(ObserverWrapper observer)
    private void considerNotify(ObserverWrapper observer) { //...省略,判断观察者是不是Active状态 observer.mLastVersion >= mVersion) { //这里很重要,保证LiveData只会接收最新的事件,防止重复分发 return; } observer.mLastVersion = mVersion; //将数据回调给观察者 observer.mObserver.onChanged((T) mData); }

执行流程分析 setValue(T value) LiveData源码解析
文章图片
setValue执行流程 postValue(T value) LiveData源码解析
文章图片
postValue执行流程 从流程图可知:我们调用 postValue()方法时,将一个Runnable抛到主线程,在Runnable中最终会调用setValue()方法。
【LiveData源码解析】当调用 setValue()后,将 mVersion++,然后调用dispatchingValue(null)方法来分发事件,参数为null则会遍历整个Observers的Map,调用Map中每一个Observer的considerNotify()方法来通知所有注册过的Observer,执行Observer.onChanged(),典型的观察者模式。
Question
  • 先调用setValue(),再打开一个全新的 Activity ,新的 Activity 如果注册了观察者,也会收到这个消息,这是怎么回事?
  • 如下代码执行后,同一个Observer中的onChanged()回调中会收到什么消息?
    liveData.postValue("1"); liveData.setValue("2");

  • 调用多次setValue(),收到什么消息?
    liveData.setValue("1"); liveData.setValue("2");

  • 调用多次postValue()呢?
    liveData.postValue("1"); liveData.postValue("2");

这几个问题很有意思也不难,LiveData 的源码只有几百行,大家看下源码,答案很容易找。

    推荐阅读