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为活跃状态。

相关推荐
还鮟3 分钟前
CTF Web的数组巧用
android
小蜜蜂嗡嗡1 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi001 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体
zhangphil3 小时前
Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
android
你过来啊你3 小时前
Android View的绘制原理详解
android
移动开发者1号6 小时前
使用 Android App Bundle 极致压缩应用体积
android·kotlin
移动开发者1号6 小时前
构建高可用线上性能监控体系:从原理到实战
android·kotlin
ii_best11 小时前
按键精灵支持安卓14、15系统,兼容64位环境开发辅助工具
android
美狐美颜sdk11 小时前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
恋猫de小郭16 小时前
Meta 宣布加入 Kotlin 基金会,将为 Kotlin 和 Android 生态提供全新支持
android·开发语言·ios·kotlin