JetPack-LiveData

目录

  1. 概述
  2. 原理简述
  3. 其他
  4. 参考

概述

Google引入该组件的原因如下:

LiveData is a data holder class that can be observed within a given lifecycle.
This means that an {@link Observer} can be added in a pair with a {@link LifecycleOwner}, and
this observer will be notified about modifications of the wrapped data only if the paired
LifecycleOwner is in active state. LifecycleOwner is considered as active, if its state is
{@link Lifecycle.State#STARTED} or {@link Lifecycle.State#RESUMED}

原理简述

核心实现在LiveData抽象类中,该类重要成员变量如下:

  • mData: 持有的数据对象
  • mVersion: 数据对象的版本号,默认值是START_VERSION(-1)
  • mObservers: Map对象(Observer <--> ObserverWrapper),其中Observer定义了观察者接口,ObserverWrapper包含LifecycleOwnerObserver和版本号mLastVersion

注意:

根据LiveData#observe方法可以得出一个Observer只能在同一个LiveData注册一次,但可以在多个不同的LiveData中注册。

网上个人感觉比较好的示意图:

关键解释:

  • LiveData通过Lifecycle感知生命周期,具体是在Lifecycle中注册LifecycleBoundObserver对象,是对ObserverWrapper对象封装,用于接收生命周期事件。

  • 当事件Event>=STARTED时,ObserverWrapper通过对比其versionLiveData的version,如果小于则认为mData有最新值,最终通知Observer;当调用LiveData#setValue()/#postValue()时,都会增加LiveData的version值,并且此时会遍历所有观察者,处于Active的观察者会立即得到通知。

  • DESTROYED事件时,LiveDataLifecycle均自动remove各自对应的观察者。

其他

  • LiveData#observeForever(Observer<? super T>)方法导致只要version有变化就会通知观察者,脱离生命周期,所以需要手动remove

  • LiveData提供两个回调函数onActvie()OnInActive(),前者表示LiveData处于actvie的观察者从0个到1个时的回调,即第一个观察者被通知前的回调,后者表示LiveData处于处于actvie的观察者从1个到0个时的回调,active表示观察者生命周期至少处于ON_START状态。

  • MutableLiveData继承LiveData,唯一作用就是暴露#setValue()/#postValue()方法。

  • MediatorLiveData继承MutableLiveData,提供在原始LiveDataObserver之间数据处理的拦截器,关键函数addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged)source表示原始LiveData,onChanged表示原始LiveData有变化时通知的回调,可进行一些处理。关于使用场景官方给出例子是Observer观察多个LiveData, 还有就是为Transformations变化提供支持。

  • Transformations类用于变换,类似Rx操作符,当前版本提供三种:

    1. map: LiveData -> LiveData, 提供Function: X->Y的转换函数实现
    2. switchMap : 功能与map类似,但需提供Function: X->LiveData的转换函数,可用于X->Y采用异步的场景
    3. distinctUntilChanged : LiveData -> LiveData, 新LiveData只在X有变化时才通知观察者。LiveData是粘性的,因为每次新增一个观察者都会比较LiveData当前version和观察者version(新增默认值是-1),如果LiveData设置过值,都会通知该观察者最新LiveData值,所以是粘性的;这个变换是为了取消这个粘性效果。

参考

1.https://www.jianshu.com/p/d66b2fd4d918
2.https://developer.android.com/topic/libraries/architecture/livedata#work_livedata
3.源码