Jetpack系列之 ---- LiveData原理分析

Jetpack系列目录:

1、 Lifecycle原理分析
2、 LiveData原理分析
3、 DataBinding原理分析
4、 Navigation原理分析


1.LiveData的使用分析

可以看出 observe() 方法有两个参数:
1)第一个参数是LifecycleOwner
2)第二个参数是observer

        MutableLiveData<String> liveData=new MutableLiveData<>();
        // observe 订阅关系
        liveData.observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.e(TAG, "onChanged: "+s );
            }
        });

2.LiveData的核心原理

1)observe方法中主要是用 LifecycleBoundObserver 将LifecycleOwner进行一次包装后,存入 mObservers 的一个Map集合中,最后addObserver方法将 observer对象 和 owner对象 的生命周期进行绑定。

 @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        	//根据 state 判断当前被观察者
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
		......
        owner.getLifecycle().addObserver(wrapper);
    }

2)LifecycleBoundObserver封装类,实现了LifecycleEventObserver接口,LifecycleEventObserver的超类接口是LifecycleObserver,所以说LifecycleBoundObserver是一个观察者的封装类。
当 被观察者生命周期发生改变的时候会调用dispatch方法最终会调用到 mLifecycleObserver.onStateChanged(owner, event)(如果不清楚建议先去了解一下Lifecycle的原理),而LifecycleBoundObserver类中也实现了这个方法。

  		@Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
        
		// 当LifecycleOwner生命周期发生变化时,调用这个函数 
        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();
            }
        }

这儿就会有removeObserver方法判断当关联的应用组件的状态变为 DESTROYED 时,移除此观察者避免内存泄露。(面试可能问)

同时还会有另一个方法 activeStateChanged(shouldBeActive()),如果shouldBeActive()返回true,则表示 compareTo(state) >= 0当前的被观察者的生命周期状态已经是可见状态了,将会执行到dispatchingValue方法中去。

    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;
    }

dispatchingValue调用地方

这个方法有两次调用,分别是 setValueactiveStateChanged 的时候。那么我们可以看看这个方法传值是否为空有什么区别。当do-while循环开始执行的时候,会先去判断initiator对象(该对象是观察者)是否为空,然后执行considerNotify方法

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

这个方法中有3个if判断
1> !observer.mActiveobserver的全局状态是不是可见状态
2>!observer.shouldBeActive()判断当前的观察者对象是否是处在可见状态
3>observer.mLastVersion >= mVersion 一个版本控制操作,每次setValue的时候mVersion就会执行++操作
4> observer.mObserver.onChanged((T) mData) 最后就会执行到观察者的 onChanged方法

3) 在onChanged的时候调用到mData,mData是用volatile 关键词修饰的,那么久有一定可能会有多线程安全问题

private volatile Object mData

4)setValue 和 postValue的区别:
主线程用setValue,而子线程用 postValue。但是其实最后postValue也是通过线程切换之后调用setValue。

    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

5)observeForever 跟上述的流程相比会更加简单,

    @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);
    }

它在绑定观察者使用的时候直接调用activeStateChanged方法,省去了UI状态的判断。

6)多线程访问、递归调用的时候会根据下面两个变量进行判断

    private boolean mDispatchingValue;//默认值false
    private boolean mDispatchInvalidated;//默认值false

dispatchingValue
这两个变量默认值都是false,同时使用的地方只有这个方法一个位置。当前observe观察者还未调用 onChanged方法时,新的一次setValue/ postValue 发送消息时,走if判断,跳出do-while循环直接发下一个被观察者的状态,这个就是连续发送消息时,LiveData为何会在被观察者处收到最后一条消息。


版权声明:本文为sinat_38167329原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。