JetPack之LiveData源码解析

LiveData是什么?

1.首先LiveData在用法上其实是与数据实体类是一样的东西,它负责暂存数据。
2.其次LiveData其实也是一个观察者模式的数据实体类,它可以跟它注册的观察者回调数据是否已经更新。
3.LiveData还能知晓它绑定的Activity或者Fragment的生命周期,它只会给前台活动的组件回调,避免组件销毁后发生意想不到的崩溃情况。

LiveData如何是如何能观察到组件生命周期的
从使用开始入手源码:
var myLiveData = MutableLiveData()

myLiveData.observe(this, Observer {

})

这里通过调用LiveData的observe()方法来注册观察者,LiveData的observe()方法如下:

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer 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);
    }

方法的第一个参数owner,就是注册时的组件,即为activity或fragment,需要为实现LifecycleOwner接口。获取组件当前的生命周期状态,如果状态为DESTROYED,那么直接return,这就保证了DESTROYED状态的组件是不允许注册的。

mObservers.putIfAbsent(observer, wrapper)方法将observer和LifecycleBoundObserver存储到SafeIterableMap类型的mObservers中,putIfAbsent方法和put方法有区别,如果传入key对应的value已经存在,就返回存在的value,不进行替换。如果不存在,就添加key和value,返回null。

最后的owner.getLifecycle().addObserver(wrapper),就在LiveData内部完成了Lifecycle的观察者的添加,这样LiveData就有了观察组件生命周期变化的能力。

LiveData是如何回调observe方法的
    class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer 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);
                return;
            }
            activeStateChanged(shouldBeActive());
        }

        @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状态时,会调用removeObserver方法,来移除observer。所以当组件销毁时,注册的生命周周观察者不会再接收到通知,因为已经解绑了。

ObserverWrapper类实现代码:

private abstract class ObserverWrapper {
        final Observer mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;

        ObserverWrapper(Observer 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);
            }
        }
    }

activeStateChanged方法定义在抽象类ObserverWrapper中,它是Observer的包装类,activeStateChanged方法会根据Active状态和处于Active状态的组件的数量,来对onActive方法和onInactive方法回调,这两个方法用于拓展LiveData对象。如果是Active状态,会调用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, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

在分发有效的前提下,遍历mObservers,一次调用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;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }

如果当前observer的mActive值不为true,就直接return。如果判断条件都满足,则调用Observer接口的onChanged()方法,这个方法正是开头myLiveData.observe(this, Observer {}) Observer接口的方法,因此完成liveData变化对observer回调事件的轮回。

public interface Observer {
    /**
     * Called when the data is changed.
     * @param t  The new data
     */
    void onChanged(T t);
}
  • Observer的回调事件通过setValue和postValue触发。
    protected void postValue(T value) {
        boolean postTask;
        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);
        }
    };

    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

@Nullable
public T getValue() {
    Object data = mData;
    // 判断mData的值是否为NOT_SET
    if (data != NOT_SET) {
        // 如果mData的值不是NOT_SET就返回这个值
        return (T) data;
    }
    // 如果mData的值为NOT_SET就返回null
    return null;
}

从代码中方法注解可以看出,setValue方法必须运行在主线程中,其内部调用了dispatchingValue方法,其后将事件通知回调给observers。首先调用 assertMainThread() 方法来判断当前线程是否为主线程,如果不是主线程,直接抛异常提醒程序员。而postValue方法里,通过任务(Runnable)的方式在主线程中更新数据。而getValue中,如果livedata中mData设过值就返回mData,否则会返回null,这里在实际使用中可能会造成空指针异常。

Livedata传相同的值会不会执行onchanged回调

看看设置值的方法,每次设置mVersion就会加1。

@MainThread
protected void setValue(T value) {
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);
}    

接着继续看后续代码:

void dispatchingValue(@Nullable ObserverWrapper initiator) {
        ....
        considerNotify(initiator);
        ....
    }

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

结论是:只要mVersion是大于等于之前的值,不管你设置了什么值,都会回调onChanged方法。

LiveData家族关联类UML图:
总结一下LiveData运行流程:

1.通过调用LiveData的observe()方法来注册观察者,获取组件当前的生命周期状态,如果状态为DESTROYED,那么直接return。owner.getLifecycle().addObserver(wrapper),就在LiveData内部完成了Lifecycle的观察者的添加,这样LiveData就有了观察组件生命周期变化的能力。

2.当组件状态发生变化时,会调用onStateChanged方法,并且判断了当组件处于DESTROYED状态时,会调用removeObserver方法来移除observer。具体事件分发是通过ObserverWrapper,它是Observer的包装类,如果是Active状态,会调用dispatchingValue方法,并将自身传进去。

3.在分发有效的前提下,遍历mObservers,如果当前observer的mActive值不为true,就直接return。如果判断条件都满足,则调用Observer接口的onChanged()方法。

4.最后,通过setValue和postValue方法内部调用dispatchingValue方法,其后将事件通知回调给observers。

你可能感兴趣的:(JetPack之LiveData源码解析)