LiveData源码浅析

首先我们来看一下LiveData是如何创建的。

ini 复制代码
public LiveData(T value) {
        mData = value;
        mVersion = START_VERSION + 1;
    }
public LiveData() {
        mData = NOT_SET;
        mVersion = START_VERSION;
    }

一般来说,LiveData会有两个构造函数,传入value和不传入value,这里的区别是:

  • 如果传入value,version会 +1。
  • 如果不传入value,则mData会被设置成NOT_SET。

首先我们先记住这个version和data,实际来看一下LiveData怎么运行的。

由于LiveData是一个观察者模式的框架,那他肯定会有的两个功能:

  • 订阅观察者
  • 给所有观察者分发数据

那我们分别看看这两个功能是怎么实现的:

首先是订阅观察者,我们一般使用LiveData的时候使用observe方法来订阅观察者:

less 复制代码
     @MainThread // 主线程
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe"); // 主线程
        if (owner.getLifecycle().getCurrentState() == DESTROYED) { // 判断当前lifeCycle状态是否为destroyed
            // ignore
            return;
        }
        // 将lifecycleOwner和 observer封装成一个wrapper
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); 
        // 把observer添加进mObservers里
        // 判读是否已存在对应的observer,如果已经存在且这个owner和存在的observer不一致会抛出异常(isAttachedTo)
        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;
        }
        // 往对应的lifecycle里添加一个wrapper
        owner.getLifecycle().addObserver(wrapper);
    }

拓展 observeForever:

java 复制代码
    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        wrapper.activeStateChanged(true);
    }

可以看到除了observe之外,LiveData还提供了一个observeForever的方法,他和observe的区别是不需要传入一个lifecycleOwner,此时构造出的wrapper则是一个AlwaysActiveObserver,根据名字可以推断出来他应该是一个永久活跃,不和生命周期进行绑定的observer。

那么第一步添加observer已经完成了,接下来我们看看mObservers这个存储observer的数据结构:

swift 复制代码
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

他是一个SafeIterableMap(双向链表实现,迭代安全的map,允许在迭代过程中进行添加/删除操作而不会抛出异常,注意只是迭代安全,并非线程安全,可以保证在通知观察者的时候,某个观察者被remove掉或者add进一个新的观察者),key是observer,value则是刚才封装的wrapper。

第二步,则是数据的一个分发,我们一般会使用setValue和postValue来分发数据,那我们一起看看这两个方法:

typescript 复制代码
    @MainThread // 主线程
    protected void setValue(T value) {
        assertMainThread("setValue");  // 主线程
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

java 复制代码
protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {  // 同步锁
            // 判断此时mPendingData是否为NOT_SET
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        // 如果不为NOT_SET,则只更新mPendingData的值
        if (!postTask) {
            return;
        }
        // post了一个runnable到主线程
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

我们继续看看这个runnable

less 复制代码
    private final Runnable mPostValueRunnable = new Runnable() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) { // 同步锁
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            // 调用setvalue
            setValue((T) newValue);
        }
    };

这里我们可以看到post和set的区别在于:

  • setValue限定了在主线程执行,而post则没有
  • post有一个pendingData机制,如果此时pendingData有值,则只更新这个值,最终的分发数据是在一个runnable里执行的,在runnable里重新调用setValue,并且把pendingData置空。
  • 其次的话,由于post是可以在子线程执行的,为了保证线程安全问题,post设置pendingData的值的时候加了锁。

可以看到最终都会走到dispatchingValue这个方法里:

ini 复制代码
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

可以看到核心逻辑就是,通过iterator遍历observer,然后调用considerNotify传入对应的wrapper。

kotlin 复制代码
    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
        //
        // we still first check observer.active to keep it as the entrance for events. So even if
        // the observer moved to an active state, if we've not received that event, we better not
        // notify for a more predictable notification order.
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

这里的最终的逻辑就是调用对应的mObserver的onChanged方法,把值传给观察者,这也是我们平时使用的时候的回调方法。然后我们需要注意在onChange之前的一些操作。

  • 如果!observer.mActive,observer不是活跃状态,则直接返回。observer.shouldBeActive()则是再次检查,确保在分发的过程中没有已经变为非活跃的observer。
  • 判断observer的上一次Version,如果大于liveData的version,则说明observer的值是比此时要通知的值更新的,所以也返回。(可能会有部分情况,在dispatch某一个值的时候停滞了一段时间,然后到该分发值的时候,observer已经被一个更新的值覆盖了,此时这个值就没用了,为了防止旧的值覆盖新值,所以有一个version)

那此时我们还有个问题需要明确:

  • observer的活跃状态是怎么判断的,又是什么时候会改变

我们看到mActive被赋值的地方:

scss 复制代码
    void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;
            changeActiveCounter(mActive ? 1 : -1);
            if (mActive) {
                dispatchingValue(this);
            }
        }

是通过activeStateChanged方法去改变mActive的值的,这里有一个地方需要注意的就是,如果mActive在这里被设置为了true,那么会触发一次dispatchingValue,这也就是为什么一个新的observer被绑定后,如果LiveData有值,会立刻收到。

最后我们看看AlwaysActiveObserver和LifecycleBoundObserver分别是怎么样确定活跃状态的。

scala 复制代码
private class AlwaysActiveObserver extends ObserverWrapper {

        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }

        @Override
        boolean shouldBeActive() {
            return true;
        }

可以看到AlwaysActiveObserver的shouldBeActive为true,并且在observeForever的时候,mActive也设置为了true,说明这是一个任何时候都活跃的observer。

less 复制代码
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }

        @Override
        boolean shouldBeActive() {
            // 只有start 和 resume为活跃状态
            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;
                // lifecycle状态改变时,改变observer的活跃状态
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }

LifecycleBoundObserver则是根据lifecycle,在start和resume的时候,observer为活跃状态。

相关推荐
恋猫de小郭2 小时前
腾讯 Kuikly 正式开源,了解一下这个基于 Kotlin 的全平台框架
android·前端·ios
贫道绝缘子3 小时前
【Android】四大组件之Activity
android
人生游戏牛马NPC1号3 小时前
学习Android(四)
android·kotlin
_祝你今天愉快3 小时前
安卓触摸事件分发机制分析
android
fyr897573 小时前
Ubuntu 下编译goldfish内核并使用模拟器运行
android·linux
心之所向,自强不息4 小时前
关于Android Studio的Gradle各项配置
android·ide·gradle·android studio
隐-梵4 小时前
Android studio学习之路(八)---Fragment碎片化页面的使用
android·学习·android studio
百锦再4 小时前
Kotlin学习基础知识大全(上)
android·xml·学习·微信·kotlin·studio·mobile
前期后期4 小时前
Android 智能家居开发:串口是什么,为什么android版本都比较低?粘包半包的原因以及处理思路,缓冲区处理,以及超时清空缓冲区....
android·智能家居
Wgllss4 小时前
按需下载!!全动态插件化框架WXDynamicPlugin解析怎么支持的
android·架构·android jetpack