Android Jetpack系列(四):LiveData (原理篇)

前言

在上一篇文章中我们学习了LiveData的基本用法, 我们知道LiveData是一个可观察的数据持有者,他是具有组件生命周期感知的,那么它是如何观察组件生命周期变化的呢?

LiveData和RxJava的不同的是,LiveData并不是通知所有观察者,它只会通知处于Active状态的观察者; 如果一个观察者处于DESTROYED状态,它将不会收到通知,这一点又是如何做到的?还有另外一点,Transformations的map方法其内部进行了什么操作?等等问题,会在这篇文章中给大家进行讲解

1.LiveData如何观察组件生命周期变化

通过调用LiveData的observe方法来注册观察者,LiveData的observe方法如下所示。

 @MainThread    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {        assertMainThread("observe");        //如果被观察者的当前的状态是DESTROYED,就return        if (owner.getLifecycle().getCurrentState() == DESTROYED) {//1            return;        }        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//2        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);//3        if (existing != null && !existing.isAttachedTo(owner)) {            throw new IllegalArgumentException("Cannot add the same observer"                    + " with different lifecycles");        }        if (existing != null) {            return;        }        owner.getLifecycle().addObserver(wrapper);//4    }

注释1处的owner实际上就是注册时传进来来组件; 比如Activity,获取组件当前的状态,如果状态为DESTROYED,那么直接return,这说明DESTROYED状态的组件是不允许注册的。

注释2处新建了一个LifecycleBoundObserver包装类,将owner和observer传了进去

注释3处将observer和LifecycleBoundObserver存储到SafeIterableMap, ObserverWrapper>mObservers中; putIfAbsent方法和put方法有区别,如果传入key对应的value已经存在,就返回存在的value,不进行替换。如果不存在,就添加key和value,返回null。 如果等于null,在注释4处会将LifecycleBoundObserver添加到Lifecycle中完成注册,这样当我们调用LiveData的observe方法时,实际上是LiveData内部完成了Lifecycle的观察者的添加,这样LiveData自然也就有了观察组件生命周期变化的能力。

2.LiveData的observe方法回调

LifecycleBoundObservers是LiveData的内部类,代码如下所示

 class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {        @NonNull final LifecycleOwner mOwner;        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {            super(observer);            mOwner = owner;        }        @Override        boolean shouldBeActive() {            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);        }        @Override        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {                removeObserver(mObserver);//1                return;            }            activeStateChanged(shouldBeActive());//2        }        @Override        boolean isAttachedTo(LifecycleOwner owner) {            return mOwner == owner;        }        @Override        void detachObserver() {            mOwner.getLifecycle().removeObserver(this);        }    }

LifecycleBoundObserver继承了ObserverWrapper类; 重写了shouldBeActive方法,用于判断当前传入的组件的状态是否是Active的,Active状态包括STARTED和RESUMED状态

LifecycleBoundObserver实现了GenericLifecycleObserver接口; 当组件状态发生变化时,会调用onStateChanged方法,当组件处于DESTROYED状态时,会调用注释1处的removeObserver方法,来移除observer。 这样在文章开头的疑问就解决了,为什么一个观察者(组件)处于DESTROYED状态时,它将不会收到通知

接着会调用注释2处的activeStateChange方法,代码如下所示

  private abstract class ObserverWrapper {        final Observer<? super T> mObserver;        boolean mActive;        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;            boolean wasInactive = LiveData.this.mActiveCount == 0;            LiveData.this.mActiveCount += mActive ? 1 : -1;            if (wasInactive && mActive) {                onActive();            }            if (LiveData.this.mActiveCount == 0 && !mActive) {                onInactive();            }            if (mActive) {                dispatchingValue(this);//1            }        }    }

activeStateChanged方法定义在抽象类ObserverWrapper中; 它是Observer的包装类,activeStateChanged方法会根据Active状态和处于Active状态的组件的数量,来对onActive方法和onInactive方法回调,这两个方法用于拓展LiveData对象。注释1处,如果是Active状态,会调用dispatchingValue方法,并将自身传进去

  private void dispatchingValue(@Nullable ObserverWrapper initiator) {        //正在处于分发状态中        if (mDispatchingValue) {            //分发无效            mDispatchInvalidated = true;//1            return;        }        mDispatchingValue = true;        do {            //分发有效            mDispatchInvalidated = false;            if (initiator != null) {                considerNotify(initiator);                initiator = null;            } else {                for (Iterator, ObserverWrapper>> iterator =                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {                    considerNotify(iterator.next().getValue());                    if (mDispatchInvalidated) {                        break;                    }                }            }        } while (mDispatchInvalidated);        //标记不处于分发状态        mDispatchingValue = false;    }

mDispatchingValue用于标记当前是否处于分发状态中; 如果处于该状态,则在注释1处标记当前分发无效,直接return;一路调用过来,ObserverWrapper是不为null的,ObserverWrapper为null的情况第3小节会讲到,无论是那种情况,都会调用considerNotify方法,代码如下所示

    private void considerNotify(ObserverWrapper observer) {        if (!observer.mActive) {//1            return;        }        if (!observer.shouldBeActive()) {            observer.activeStateChanged(false);//2            return;        }        if (observer.mLastVersion >= mVersion) {            return;        }        observer.mLastVersion = mVersion;        //noinspection unchecked        observer.mObserver.onChanged((T) mData);//3    }

considerNotify方法中做了多次的判断; 注释1处,如果ObserverWrapper的mActive值不为true,就直接return;注释2处,如果当前observer对应组件的状态不是Active,就会再次调用activeStateChanged方法,并传入false,其方法内部会再次判断是否执行onActive方法和onInactive方法回调

如果判断条件都满足会调用Observer的onChanged方法,这个方法正是使用LiveData的observe方法的回调

3.postValue/setValue方法分析

当调用MutableLiveData的observe方法后,还需要通过postValue/setValue方法来更新数据

...  private final Runnable mPostValueRunnable = new Runnable() {        @Override        public void run() {            Object newValue;            synchronized (mDataLock) {                newValue = mPendingData;                mPendingData = NOT_SET;            }            //noinspection unchecked            setValue((T) newValue);//1        }    };    ...    protected void postValue(T value) {        boolean postTask;        synchronized (mDataLock) {            postTask = mPendingData == NOT_SET;            mPendingData = value;        }        if (!postTask) {            return;        }        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);//2    }    @MainThread //3    protected void setValue(T value) {        assertMainThread("setValue");        mVersion++;        mData = value;        dispatchingValue(null);    }

postValue/setValue方法都定义在LiveData中; 根据注释1和注释2处,可以发现postValue方法实际上就是将setValue方法切换到主线程调用。注释3处说明setValue方法是运行在主线程中的,其内部调用了dispatchingValue方法,这个方法在第2小节介绍过,也就是dispatchingValue方法的参数ObserverWrapper为null的情况

从这里我们可以知道,无论是LiveData的observe方法还是LiveData的postValue/setValue方法都会调用dispatchingValue方法

4.Transformations.map方法分析

除了以上讲的常用的方法之外,还可能会使用到Transformations.map和Transformations.switchMap方法,这里以Transformations.map为例; 这个方法用来在LiveData对象分发给观察者之前对其中存储的值进行更改, 代码如下所示

@MainThread    public static  LiveData map(            @NonNull LiveData source,            @NonNull final Function mapFunction) {        final MediatorLiveData result = new MediatorLiveData<>();//1        result.addSource(source, new Observer() {            @Override            public void onChanged(@Nullable X x) {                result.setValue(mapFunction.apply(x));            }        });        return result;    }

Transformations.map方法运行在主线程,注释1处创建了MediatorLiveData,紧接着调用了它的addSource方法:

  */    @MainThread    public  void addSource(@NonNull LiveData source, @NonNull Observer<? super S> onChanged) {        Source e = new Source<>(source, onChanged);//1        Source<?> existing = mSources.putIfAbsent(source, e);        if (existing != null && existing.mObserver != onChanged) {            throw new IllegalArgumentException(                    "This source was already added with the different observer");        }        if (existing != null) {            return;        }        if (hasActiveObservers()) {            e.plug();//2        }    }

注释1处将传进来的LiveData和onChanged封装到Source类中,注释2处调用了Source的plug方法:

 private static class Source implements Observer {        final LiveData mLiveData;        final Observer<? super V> mObserver;        int mVersion = START_VERSION;        Source(LiveData liveData, final Observer<? super V> observer) {            mLiveData = liveData;            mObserver = observer;        }        void plug() {            mLiveData.observeForever(this);//1        }        void unplug() {            mLiveData.removeObserver(this);        }        @Override        public void onChanged(@Nullable V v) {            if (mVersion != mLiveData.getVersion()) {                mVersion = mLiveData.getVersion();                mObserver.onChanged(v);//2            }        }    }

注释2处可以看到,Transformations.map方法传入的Observer的回调在这里进行处理; 注释1处,Source的plug方法会调用LiveData的observeForever方法,这个和第2小节所讲的内容有什么区别呢?我们再往下看

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

注释1处用AlwaysActiveObserver来对Observer进行包装,紧接着调用AlwaysActiveObserver的activeStateChanged方法; 其内部实际调用的是ObserverWrapper的activeStateChanged方法,这个在第二小节已经做了分析,就不再赘述了。来看AlwaysActiveObserver类是如何定义的

   private class AlwaysActiveObserver extends ObserverWrapper {        AlwaysActiveObserver(Observer<? super T> observer) {            super(observer);        }        @Override        boolean shouldBeActive() {            return true;        }    }

AlwaysActiveObserver是LiveData的内部类; 它继承自ObserverWrapper,AlwaysActiveObserver是LiveData的内部类和ObserverWrapper的区别就是,它是永远处于Active状态的

5.LiveData关联类

其中MutableLiveData继承自LiveData,LifecycleOwner和Observer和LiveData有关联的关系,ObserverWrapper是Observer的包装类,因此它们有着关联的关系

有需要文中完整代码的同学:现在私信发送 "底层源码" 即可免费获取

现在私信发送 "笔记" 还可以获取《更多 Android 源码解析+学习大纲+核心笔记》

最后我想说:

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们

技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面

Android 架构师之路还很漫长,与君共勉

页面更新:2024-05-12

标签:部类   观察者   小节   主线   注释   生命周期   组件   状态   代码   方法   系列

1 2 3 4 5

上滑加载更多 ↓
Top