LiveData源码解析

作者: 雯艺雪 | 来源:发表于2019-08-15 17:23 被阅读1次

    0.前言

    关于livedata的使用详情见LiveData+ViewModel+RxJava2+autoDisposable解决内存泄漏,废话也在里面。
    啥嘚,撸起袖子撸代码吧。

    1. liveData使用

    官方文档可见,liveData提供了几个方法可使用(日常使用的就四个):observer,observerForever,postValue和setValue(省略方法的参数名),者几个方法的区别主要如下:

    • observer用于订阅观察者,实现在Activity(LifecycleOwner)处于活跃状态下执行onChange方法
    • observerForever:setValue之后立马回调onChange,不管lifeCycleOwner生命周期,需要手动移除订阅
    • setValue更新liveData的数据,只能在UI线程调用,否则报错,liveData订阅的Observer的onChange方法将在调用的线程中执行
    • postValue,liveData订阅的Observer的onChange方法将在主线程中执行,内部调用setValue(所以,这厮就是个回调方法运行在主线程的setValue而已)

    so,下面就从这几个方法切入分析源码
    让我们一步步揭开liveData的神秘面纱

    2. observe

    @MainThread
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
            //如果owner所在Activity或Fragment处于消亡状态下,直接返回
            if (owner.getLifecycle().getCurrentState() == DESTROYED) {
                // ignore
                return;
            }
            //  内部定义的一个Observer,将owner和observer包装起来
            LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
           //mObservers是缓存的SafeIterableMap,继承Iterable接口,此处判断Observer是否已经存在
            ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
            //如果已经存在,且与此owner的Observer不一致,抛出异常
            if (existing != null && !existing.isAttachedTo(owner)) {
                throw new IllegalArgumentException("Cannot add the same observer"
                        + " with different lifecycles");
            }
            //已经存在,返回
            if (existing != null) {
                return;
            }
            //否则,将包装了owner和Observer的wrapper 添加到owner中
            //因此,当owner的生命周期发生变化时,可以调用LifecycleBoundObserver 的onStateChange方法
            owner.getLifecycle().addObserver(wrapper);
        }
    

    And Then:

    • LifecycleBoundObserver
    //LifecycleBoundObserver 继承于内部类ObserverWrapper实现GenericLifecycleObserver ,实现onStateChanged方法
    class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
            @NonNull final LifecycleOwner mOwner;//缓存传递过来的owner
    
            LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
                super(observer);//将Observer传给父类ObserverWrapper
                mOwner = owner;
            }
    
            //判断是否需要激活,当生命周期为STARTED/RESUMED状态下返回true
            //具体源码查看lifecycle
            @Override
            boolean shouldBeActive() {
                return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
            }
    
            //当owner的生命周期变化时,调用此方法
            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                    //如果已经消亡,移除掉Observer,然后返回
                    //看吧,所以我们不需要手动移除Observer,内部帮我们实现了
                    removeObserver(mObserver);
                    return;
                }
                //否则调用shouldBeActive判断是否要激活状态,传递给activeStateChanged
                activeStateChanged(shouldBeActive());
            }
    
          //判断改Observer是否已经添加了
            @Override
            boolean isAttachedTo(LifecycleOwner owner) {
                return mOwner == owner;
            }
          
          //移除Observer
            @Override
            void detachObserver() {
                mOwner.getLifecycle().removeObserver(this);
            }
        }
    

    然后再调用activeStateChanged的方法进入下一步,实际上是调用父类ObserverWrapper 的activeStateChanged方法,按照“因为都是一样的操作嘛,所以放在父类最好的了”这样的设计思想实现

    • ObserverWrapper
    //刚才说了,LifecycleBoundObserver 会包装owner和Observer,就是这厮搞的鬼
    private abstract class ObserverWrapper {
            final Observer<T> mObserver;
            boolean mActive;//记录是否处于活跃状态
            int mLastVersion = START_VERSION;//记录版本号,用于判断数据是否需要更新
    
            ObserverWrapper(Observer<T> observer) {
                mObserver = observer;
            }
          
            //这里不解释
            abstract boolean shouldBeActive();
          
            //别问我,不解释
            boolean isAttachedTo(LifecycleOwner owner) {
                return false;
            }
            
            //>_<
            void detachObserver() {
            }
          
            //更新状态(是否激活)
            void activeStateChanged(boolean newActive) {
                if (newActive == mActive) {
                    return;
                }
                // immediately set active state, so we'd never dispatch anything to inactive
                // owner
                mActive = newActive;
                boolean wasInactive = LiveData.this.mActiveCount == 0;
                LiveData.this.mActiveCount += mActive ? 1 : -1;//当newActive为true,增加计数点
                //当mActiveCount 为1时调用onActive
                if (wasInactive && mActive) {
                    onActive();//这厮是个空方法
                }
                //当mActiveCount 为0时调用,所有Observer都被移除之后调用,所以此方法可用于结束时释放资源
                if (LiveData.this.mActiveCount == 0 && !mActive) {
                    onInactive();
                }
                //复活后更新
                //实际场景就是,使用setValue更新数据时,activity处于濒死状态(onPause或onStop)时,
                //setValue调用dispatchingValue(稍后介绍)直接返回,当Activity复活后(到前台了),就会调用此方法,从而实现仅在activity处于活跃状态下更新数据
                if (mActive) {
                    //处理数据
                    dispatchingValue(this);
                }
            }
        }
    

    如注释所言,liveData只会在activity处于活跃状态下更新数据,看起来很神秘,现在你知道为什么了吧,其实就是这么简单,activity复活后重新调用一次LifecycleBoundObserver 的onStateChange,然后就是activeStateChanged......

    接下来是 dispatchingValue:
    private void dispatchingValue(@Nullable ObserverWrapper initiator) {
            //防止重复分发相同的内容
            if (mDispatchingValue) {
                mDispatchInvalidated = true;
                return;
            }
            mDispatchingValue = true;
            do {
                mDispatchInvalidated = false;
              //当initiator != null,只处理当前Observer
                if (initiator != null) {
                    considerNotify(initiator);
                    initiator = null;
                } else {
                    //否则遍历所有的Observer,进行分发
                    for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                            mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                        considerNotify(iterator.next().getValue());//更新数据
                        if (mDispatchInvalidated) {
                            break;
                        }
                    }
                }
            } while (mDispatchInvalidated);
            mDispatchingValue = false;
        }
    

    当initiator != null,只处理当前Observer,否则遍历所有的Observer,进行分发。这里怎么理解呢?怎么会有多个呢?前面也已经说了,这还是因为activity濒死时调用setValue多次的原因。

    接下来是considerNotify:
    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;
            //noinspection unchecked
            observer.mObserver.onChanged((T) mData);//Observer的onChanged方法终于调用了
        }
    

    这里最后时调用了onChanged方法更新数据。初次自制流程图,图片太大勿喷

    observe.png

    3.setValue

    @MainThread
        protected void setValue(T value) {
            //一开头就要求运行在主线程
            assertMainThread("setValue");
            mVersion++;//版本号更新
            mData = value;//缓存数据
            dispatchingValue(null);//什么啊,还是调用dispatchingValue呀
        }
    

    然后就调用了dispatchingValue方法,前面已经介绍了,先介绍observe,没毛病

    setValue.png

    4.postValue

    protected void postValue(T value) {
            boolean postTask;
            //进程锁住,因此liveData是线程安全的
            synchronized (mDataLock) {
              //判断是否没有在处理数据
                postTask = mPendingData == NOT_SET;
                mPendingData = value;
            }
            if (!postTask) {
                return;
            }
            ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);//到主线程去处理
        }
    
     private final Runnable mPostValueRunnable = new Runnable() {
            @Override
            public void run() {
                Object newValue;
                synchronized (mDataLock) {
                    newValue = mPendingData;
                    mPendingData = NOT_SET;//处理完了
                }
                //noinspection unchecked
                setValue((T) newValue);//实际上调用的还是setValue方法
            }
        };
    
    postValue.png

    啥嘚啥嘚,最后一个:

    5.observeForever

     @MainThread
        public void observeForever(@NonNull Observer<T> observer) {
            AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
            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);
        }
    
    private class AlwaysActiveObserver extends ObserverWrapper {
    
            AlwaysActiveObserver(Observer<T> observer) {
                super(observer);
            }
    
            @Override
            boolean shouldBeActive() {
                return true;
            }
        }
    
    

    诶多,跟observe很像,只不过用来封装owner和observer的是AlwaysActiveObserver ,而AlwaysActiveObserver 并没有像LifecycleBoundObserver 那样继承于内部类ObserverWrapper实现GenericLifecycleObserver,所以自然不会根据Activity的生命周期回调onStateChange方法,当然也就不会自动移除observer啦,必须要手动移除。

    以上!

    6.总结

    本文通过源码分析,解决了

    • liveData只在activity(lifecycleowner)处于活跃状态下更新数据的原因
    • setValue和postValue更新数据时,activity处于非活跃状态,activity重回前台后继续更新数据的原因
    • liveData防止内存泄漏的原因以及自动移除Observer的原因

    原创文章,转载请附上https://www.jianshu.com/p/943770f22470

    相关文章

      网友评论

        本文标题:LiveData源码解析

        本文链接:https://www.haomeiwen.com/subject/hqdzjctx.html