前言 前面我们讲到了LiveData是如何使用的,并在最后留了几个问题。比如它是如何通过生命周期去变化的?为什么DESTORY不会接受数据?postValue和setValue是如何更新数据的?Transformations的map和switchMap方法内部是如何操作的?别急,本篇文章会带你了解其原理。接下来上正文。
LiveData是如何观察生命周期变化的? 如何观察生命周期,我们需要通过他的observe方法去看,我们上源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @MainThread public void observe (@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { assertMainThread("observe" ); if (owner.getLifecycle().getCurrentState() == DESTROYED) { 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); }
我在源码加了几个注释,我们一个个看。
注释一:可以看出通过当前组件的LifecycleOwner拿到生命周期的状态,如果是DESTORY就返回,不做任何处理。
注释二:新建了一个LifecycleBoundObserver包装类,并把owner和observer丢进去。
注释三:将observer和wrapper做一个存储。我们看下putIfAbsent方法:
1 2 3 4 5 6 7 8 public V putIfAbsent (@NonNull K key, @NonNull V v) { Entry<K, V> entry = get(key); if (entry != null ) { return entry.mValue; } put(key, v); return null ; }
可以看出,如何这个entry存在的话,不像正常map做替换,而且直接拿到对应的value。不存在的话正常put操作。
注释四:判断这个owner是否存在,如何存在就抛出异常,提示无法添加具有不同生命周期的同一观察者。
注释五:将LifecycleBoundObserver添加到Lifecycle中完成注册,所以我们LiveData的生命周期观察其实来源于LifecycleOwner,这也就是为什么LiveData具备了观察组件生命周期变化的能力。
observe是如何同步数据的? 上面代码中我们知道有一个LifecycleBoundObserver的包装类。我们看看其实现逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver { @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 (@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(); } } @Override boolean isAttachedTo (LifecycleOwner owner) { return mOwner == owner; } @Override void detachObserver () { mOwner.getLifecycle().removeObserver(this ); } }
我们来关注几个方法。通过ObserverWrapper实现了shouldBeActive。从命名上可以看出判读是否活跃。从代码看来也就是STARTED和RESUMED。
在看另一个,通过LifecycleEventObserver实现了onStateChanged方法。我们可以看到如果当前的STATE是DESTROYED时会移除观察者监听。接着通过判读状态是否匹配调用了activeStateChanged方法。因为prevState定义为null。所以此方法最少执行一次。那么我们看看它是如何处理的。
1 2 3 4 5 6 7 8 9 10 11 12 void activeStateChanged (boolean newActive) { if (newActive == mActive) { return ; } mActive = newActive; changeActiveCounter(mActive ? 1 : -1 ); if (mActive) { dispatchingValue(this ); } }
可以看到它会先调用changeActiveCounter,字面意思也就是改变活跃的数量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @MainThread void changeActiveCounter (int change) { int previousActiveCount = mActiveCount; mActiveCount += change; if (mChangingActiveState) { return ; } mChangingActiveState = true ; try { while (previousActiveCount != mActiveCount) { boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0 ; boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0 ; previousActiveCount = mActiveCount; if (needToCallActive) { onActive(); } else if (needToCallInactive) { onInactive(); } } } finally { mChangingActiveState = false ; } }
从逻辑上我们可以看出previousActiveCount默认为0,mActiveCount可能为1,可能为-1,mChangingActiveState默认为flase。也就是一定会走进while循环里面去。从里面代码可以看出需要通知组件存活状态就调用onActive,需要通知组件不活跃就调用onInactive。然后我们往回看,如果组件是活跃的就会调用dispatchingValue方法。我们接着看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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 ; }
注释一中mDispatchingValue用于标记当前是否处于分发状态中,如果是存在分发状态,则执行注释二表示分发无效并直接return。注释三则将分发状态修改成有效状态。我们可以看到后面无论initiator是否为null都会执行considerNotify方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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); }
可以看到当前状态如果是非活跃的就直接return了。接着判读了如果当前observer对应组件的状态不是Active,就会再次调用activeStateChanged方法,并传入false,其方法内部会再次判断是否执行onActive方法和onInactive方法回调。接着就会调用Observer的onChange方法通知数据更新。
postValue和setValue的区别是什么? 我们知道虽然我们调用observe方法对数据进行观察,但是真正同步数据的代码是postValue和setValue。话不多说,上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 private final Runnable mPostValueRunnable = new Runnable() { @SuppressWarnings("unchecked") @Override public void run () { Object newValue; synchronized (mDataLock) { newValue = mPendingData; mPendingData = NOT_SET; } setValue((T) newValue); } }; ... protected void postValue (T value) { boolean postTask; synchronized (mDataLock) { postTask = mPendingData == NOT_SET; mPendingData = value; } if (!postTask) { return ; } ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); } @MainThread protected void setValue (T value) { assertMainThread("setValue" ); mVersion++; mData = value; dispatchingValue(null ); }
我们看到setValue加上了@MainThread注解,也就是在主线程中执行,并且会调用dispatchingValue传入null。这个前面我们有提到过。而postValue其实是在子线程操作,最后通过postToMainThread同步至主线程,最后其实还是调用了setValue方法。
前面我们在使用篇时有提到Transformations有2个方法,一个是map。一个是switchMap。我们一个个的看。
map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @MainThread @NonNull public static <X, Y> LiveData<Y> map ( @NonNull LiveData<X> source, @NonNull final Function<X, Y> mapFunction) { final MediatorLiveData<Y> result = new MediatorLiveData<>(); result.addSource(source, new Observer<X>() { @Override public void onChanged (@Nullable X x) { result.setValue(mapFunction.apply(x)); } }); return result; }
我们可以看到此处调用了MediatorLiveData的addSource方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @MainThread public <S> void addSource (@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) { Source<S> e = new Source<>(source, onChanged); 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(); } }
可以看到最后一个判断,如果存在活跃的观察者,即调用Source的plug方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 private static class Source <V > implements Observer <V > { final LiveData<V> mLiveData; final Observer<? super V> mObserver; int mVersion = START_VERSION; Source(LiveData<V> liveData, final Observer<? super V> observer) { mLiveData = liveData; mObserver = observer; } void plug () { mLiveData.observeForever(this ); } void unplug () { mLiveData.removeObserver(this ); } @Override public void onChanged (@Nullable V v) { if (mVersion != mLiveData.getVersion()) { mVersion = mLiveData.getVersion(); mObserver.onChanged(v); } } }
我们可以看到Source提供了添加观察者,移除观察者,以及监听的操作。哎,不对,是不是发现哪里有点问题?这里它调用的是observeForever,而不是addObserver。那我们接着看:
1 2 3 4 5 6 7 8 9 10 11 12 13 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 ); }
可以看出,这里最后其实还是调用了ObserverWrapper的activeStateChanged方法。
switchMap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @MainThread @NonNull public static <X, Y> LiveData<Y> switchMap( @NonNull LiveData<X> source, @NonNull final Function <X, LiveData<Y>> switchMapFunction) { final MediatorLiveData<Y> result = new MediatorLiveData<>(); result.addSource(source, new Observer<X>() { LiveData<Y> mSource; @Override public void onChanged (@Nullable X x ) { LiveData<Y> newLiveData = switchMapFunction.apply(x); if (mSource == newLiveData) { return ; } if (mSource != null ) { result.removeSource(mSource); } mSource = newLiveData; if (mSource != null ) { result.addSource(mSource, new Observer<Y>() { @Override public void onChanged (@Nullable Y y ) { result.setValue(y); } }); } } }); return result; }
可以看出来,整体和map类似,只是内部包装了一层,让其返回结果是一个LiveData而已。
总结 本篇我们整体介绍了LiveData的使用原理,也就是上篇文章遗留下来的几个问题。总之,我们不仅需要知其然,还需要知其所以然。
参考 Android Jetpack架构组件(五)带你了解LiveData(原理篇)