LiveData 源码分析

121 阅读4分钟

1. LiveData简介

1.LiveData 是一种可观察的数据存储器类。 与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 activity、fragment 或 service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

2.观察者生命周期在STARTED 或 RESUMED状态, LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察 LiveData 对象而注册的非活跃观察者不会收到更改通知。

3.当activity 或 fragment销毁时,系统会自动移除数据观察者

2. Livedata 简单使用

vm.livedata.observe(this){
  
}
livedata.value = ""

3. 源码分析

1. liveDta 如何感知生命周期的变化,

livedata.observe(this)

abstract class LiveData<T> {
    
    //观察者容器   
    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
        new SafeIterableMap<>();
    
    //owner 生命周期拥有者
    //observer 数据观察类
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //当生命周期状态==DESTROYED时,不会添加
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            //
            return;
        }
        // 将owner和observer组合,使得LifecycleBoundObserver拥有生命周期和数据观察2种功能
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        //不能重复添加
        if (existing != null) {
            return;
        }
        //注册生命周期,这样LifecycleBoundObserver就能感知owner生命周期的变化
        //重新添加的的观察者会重走各个生命周期直到相等
        //这也是时livedata粘性的关键之一
        owner.getLifecycle().addObserver(wrapper);
    }

}

LifecycleBoundObserver

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    //生命周期拥有着
    final LifecycleOwner mOwner;
    
    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
        //包装成 ObserverWrapper
        super(observer);
        mOwner = owner;
    }
    //当前生命周期状态至少大于STARTED
    @Override
    boolean shouldBeActive() {
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }
    
    //生命周期发生改变
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
        //从观察者列表种移除
        if (currentState == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        Lifecycle.State prevState = null;
        while (prevState != currentState) {
            prevState = currentState;
            //状态变化通知,
            activeStateChanged(shouldBeActive());
            currentState = mOwner.getLifecycle().getCurrentState();
        }
    }
    //是否关联了生命周期持有者
    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        return mOwner == owner;
    }
    
    //移除生命周期观察者监听
    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}

ObserverWrapper

private abstract class ObserverWrapper {
    //真正观察者
    final Observer<? super T> mObserver;
    //是否活跃
    boolean mActive;
    //当前数据观察者的版本号 -1
    int mLastVersion = START_VERSION;

    ObserverWrapper(Observer<? super T> observer) {
        mObserver = observer;
    }

    abstract boolean shouldBeActive();

    boolean isAttachedTo(LifecycleOwner owner) {
        return false;
    }

    void detachObserver() {
    }
    
    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            return;
        }
        mActive = newActive;
        changeActiveCounter(mActive ? 1 : -1);
        if (mActive) {
            //活跃状态下分发数据
            //它时粘性的,当新添加的观察者处于活跃时,分发
            dispatchingValue(this);
        }
    }
}

2.livedata 如何储存和分发数据的

LiveData

abstract class LiveData<T> {
    
    final Object mDataLock = new Object();
    //初始版本号
    static final int START_VERSION = -1;
    static final Object NOT_SET = new Object();

    int mActiveCount = 0;
    //当前存储数据
    private volatile Object mData;
    //初始值
    volatile Object mPendingData = NOT_SET;
    //当前版本号
    private int mVersion;

}

setValue

@MainThread
protected void setValue(T value) {
    assertMainThread("setValue");
    //版本号++
    mVersion++;
    //赋值给成员mData,
    mData = value;
    //分发给当前的活跃的观察者
    dispatchingValue(null);
}

postValue 会丢失值

当频繁使用postValue()更新时,post(1)但第一次的mPostValueRunnable消息还没执行,
第二次post(2) 的值已经更新了mPendingData = 2,
导致第一次的Runnable拿到的是第二次的 2,第一次post(1)会被覆盖,
导致数据丢失。
protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        //将值暂时存到mPendingData中
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    //向主线程发生消息
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            //获取postValue存储的值
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        //分发
        setValue((T) newValue);
    }
};

dispatchingValue

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        //当某观察者持有的生命周期状态发生变化时,通知更新
        if (initiator != null) {
            considerNotify(initiator);
            initiator = null;
        } else {
            //value值发生改变时
            //遍历所有的观察者
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

considerNotify

private void considerNotify(ObserverWrapper observer) {
    //当前观察者是否活跃
    if (!observer.mActive) {
        return;
    }
    // 检查当前生命周期组件状态是否活跃
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    //当前观察者的版本号 >= LiveData版本号,
    //说明已经分发过,值已经时最新的了
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    //更新观察者版本号
    observer.mLastVersion = mVersion;
    //通知观察者,数据更新
    observer.mObserver.onChanged((T) mData);
}

4. 总结

LiveData是能感知生命周期,粘性,可观察的数据存储器类。
通过Lifecycle感知生命周期的变化,确保LiveData只更新处于活跃活跃生命周期状态的应用组件观察者,
通过储存value值和lifecycle来通知观察者更新旧值。

为了使用方便,官方还提供了多个转换操作:

androidx.lifecycle.Transformations

//map livedata值的变换
val liveData1 = _livedata.map { 
    it.length
}

//switchMap 一个livedata的变化,触发另一个livedata的更新
//一对一
val liveData2 = _livedata.switchMap {
   val liveData =  MutableLiveData<String>()
    liveData.value = it
    liveData
}

//去重操作符
_livedata.distinctUntilChanged()

//mediatorLiveData 可监听多个livedata数据源的变化
//一对多
val mediatorLiveData = MediatorLiveData<Any>()
mediatorLiveData.addSource(liveData1){
    mediatorLiveData.value = it
}
mediatorLiveData.addSource(liveData2){
    mediatorLiveData.value = it
}

//上述操作都发生在主线程,当处理复杂业务liveData{}
//CoroutineLiveData

//默认在主线程的协程中运行,
//可指定上下文分发器,如Io线程
val livedata = _livedata.switchMap {
    liveData(Dispatchers.IO){
        emit("xxx")
    }
}


5. 协程详解