前言
在一通研究下,我打算LiveData的解析通过从使用的方法上面切入进行LiveData的工作原理分析😋。感觉这样子更能让大家伙理解明白,LiveData的实现和Lifecycle分不开,并且还得需要知道LiveData的使用会用到什么样的方法。所以,还不了解这两者的朋友可以看一下我之前写的博客:
前置知识
jetpack之lifecycle的原理分析
https://blog.csdn.net/i_xiang_la_shi/article/details/147191937?fromshare=blogdetail&sharetype=blogdetail&sharerId=147191937&sharerefer=PC&sharesource=i_xiang_la_shi&sharefrom=from_linkjetpack之LiveData的简单使用(特别简单,让你爽到飞!)
https://blog.csdn.net/i_xiang_la_shi/article/details/147309717?fromshare=blogdetail&sharetype=blogdetail&sharerId=147309717&sharerefer=PC&sharesource=i_xiang_la_shi&sharefrom=from_link
LiveData的几个方法:
setValue:
虽然kotlin在使用LiveData的时候看似是直接赋值,其实是调用了setValue的方法。我们先来看setValue的源码:
    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    } 
通过代码我们可以观察到一个MainThred的注解,这说明setValue是一定要运行在主线程上的(也就是UI线程)。
mVersion是决定此事件是否为粘性事件的关键,如果mVersion>mLastVersion,那么就不是粘性事件,直接进行分发。
mData也就是数据了。
dispatchingValue看名字像是分发值,进入此方法,我们能发现他进行了一个遍历:
@SuppressWarnings("WeakerAccess") /* synthetic access */
    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会遍历观察者列表,根据活跃状态和版本号决定是否分发数据(在considerNotify中有所体现)。
为什么我笃定它在setvalue中执行的时候就一定会遍历观察者列表呢?因为在setValue中他永远都发送的null,总会进入到else分支。
ObserverWrapper在后面的observe方法会简单讲一下
postValue:
接下来趁热打铁看一下postValue👌。
protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    } 
我们可以看到最后一行有一个postToMainThread的方法 。证明这个方法可以在子线程中运行,不过最终还是得去主线程。
点进这个Runnable参数看一下->

还是看最后一行:postValue最终还是通过setValue进行数据的修改。
所以,我们可以说,postValue通过 Handler 切换到主线程执行 setValue(),支持子线程更新
getValue:
看完setValue接着我们来看看getValue:
@Nullable
    public T getValue() {
        Object data = mData;
        if (data != NOT_SET) {
            return (T) data;
        }
        return null;
    } 
好像就是一个获取data值的操作 😶
observer:
接下来是重头戏了,看看observer是怎么实现数据更新他就知道的:
@MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        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;
        }
        owner.getLifecycle().addObserver(wrapper);
    } 
一样是运行在主线程的(这不废话),毕竟不在主线程也感知不到生命周期的变化😄
我们先看老熟人——ObserverWrapper
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;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;
            changeActiveCounter(mActive ? 1 : -1);
            if (mActive) {
                dispatchingValue(this);
            }
        }
    } 
在里面有几个关键的成员属性:mActive和mLastVersion 。虽然只有一个avtivaStateChanged的方法,但是通过这个方法我们就能管中窥豹——LiveData在程序活跃的时候才会进行数据的观察和修改。
接下来我们再看LifecycleBoundObserver,Lifecycle也是老演员了,我们来看看这个Owner是怎么个事:
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;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        } 
源码太多,但是这个方法像是鹤立鸡群那只鹤有,直接被我捕获到了哈哈哈(事实是抱着侥幸的心理查找了一下changed😜)
LifecycleBoundObserver看来就是告诉livedataOwner的生命周期改变了。
好了,大概就这么多
求关注
感觉主包讲的还可以可以给个关注😋


![Vue3 + TypeScript,关于item[key]的报错处理方法](https://i-blog.csdnimg.cn/direct/27de1eb52d7d48ccab56a9f035156e49.png)
















