前言
上一篇我们讲解了Jetpack中LiveData使用篇, 本片我们从源码角度来分析LiveData
.是如何实现的。
本篇目录如下:
- LiveData源码分析
- LiveData.setValue/postValue源码分析
- Transformations.map()的源码分析
LiveData源码分析
- 我们先以上一篇的基本使用入手来分析源码
class TestActivity : AppCompatActivity() { private val TAG by lazy { TestActivity::class.java.simpleName } private val data = MutableLiveData<String>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //-----1----- data.observe(this, Observer { Log.i(TAG, "value: $it ") }) } fun onTest(view: View) { //-----2----- data.postValue("LiveData") } //打印信息 TestActivity: value: LiveData }
- 源码分为两个部分,第一个部分是注释1处的
observer
,第二个部分是注释2处的postValue
赋值的地方。首先看注释1处的源码:@MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { assertMainThread("observe"); //-----1----- if (owner.getLifecycle().getCurrentState() == DESTROYED) { // ignore return; } //-----2----- 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; } //-----3----- owner.getLifecycle().addObserver(wrapper); }
observer
方法传入了两个参数,第一个是LifecycleOwner
, 这个是负责管理生命周期的,另外一个参数则是Observer
,是当数据发生变化时候的回调。对于LifeCycle
不了解的可以看Android Jetpack架构组件(三)Lifecycle原理篇。- 注释1的地方,会判断当前的生命周期,如果是处于
DESTROYED
阶段的话,就不会执行后面的逻辑代码,就不会注册进入作为观察者,这样就不用担心内存泄漏的问题。 - 注释2处会生成一个
LifecycleBoundObserver
对象,它也是一个LifecycleObserver
的实现类,主要负责LiveData的处理。然后将其放入mObservers
中,mObservers
内部是一个链表的形式存储的Entry,每一个Entry包含一个Key, Value,还有一个前Entry,和一个后Entry, 这样就形成了一个链表的结构。 - 注释3处,调用
getLifecycle().addObserver
方法将LifecycleBoundObserver
注册进入,便于后面在生命周期发生变化的时候回调,这个方法在Lifecycle原理篇已经详细的讲解过,可以点击查看,注册的逻辑其实就这么多,很简单,如果了解了Lifecycle
的话非常简单。
- 接下来我们先看一下生命周期发生变化时候的回调,这里先看
LifecycleBoundObserver
的源码:class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { @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(LifecycleOwner source, Lifecycle.Event event) { //-----1----- if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } //-----2----- activeStateChanged(shouldBeActive()); } @Override boolean isAttachedTo(LifecycleOwner owner) { return mOwner == owner; } @Override void detachObserver() { mOwner.getLifecycle().removeObserver(this); } }
- 在Lifecycle原理篇中我们知道,当生命周期发生变化的时候,必然会调用
LifecycleRegistry.ObserverWithState.dispatchEvent(LifecycleOwner owner, Event event)
方法,从而运行mLifecycleObserver.onStateChanged(owner, event)
,这里实际运行的是LifecycleBoundObserver.onStateChanged(owner, event)
方法,我们就从这里开始分析。 - 注释1处首先判断当前的生命周期,如果是
DESTROYED
状态的话,就会移除观察者。所以我们不用担心在观察数据的时候内存泄漏的问题了。 - 注释2处调用
activeStateChanged(shouldBeActive())
,shouldBeActive()
会判断当前的状态是不是STARTED
或者RESUMED
状态,如果不是这两个状态的话,就不会执行下面的逻辑。所以LiveData只会将通知发送到处于Active状态的组件。但是注意一点,这里State的STARTED和RESUMED状态实际上并不和Activity的生命周期一致,其中State的STARTED指的是Activity生命周期中的onStart()和onPause(),State的RESUMED指的是Activity生命周期中的onResume(),这些可以从源码LifecycleRegistry.getStateAfter得到。
- 在Lifecycle原理篇中我们知道,当生命周期发生变化的时候,必然会调用
- 接着我们分析
activeStateChanged
方法,它在类ObserverWrapper
中,是LifecycleBoundObserver
的父类,下面看源码: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) { //-----1----- if (newActive == mActive) { return; } //-----2----- mActive = newActive; //-----3----- boolean wasInactive = mActiveCount == 0; //-----4----- mActiveCount += mActive ? 1 : -1; if (wasInactive && mActive) { //-----5----- onActive(); } if (mActiveCount == 0 && !mActive) { //-----6----- onInactive(); } if (mActive) { //-----7----- dispatchingValue(this); } } }
- 注释1处首先判断当前组件是否处于相同的状态,如果是的话就会return.
- 注释2将新的状态赋值给成员变量
mActive
,注释3处判断标记位是否当前处于Active的组件为0。 - 注释4处根据mActive的状态为
mActiveCount
赋值,如果mActive
为true就加1,否则就减1。 - 注释5和6处主要用于
自定义的LiveData
以及MediatorLiveData
。后面我们会讲解MediatorLiveData
源码。 - 注释7处调用了
dispatchingValue
,并且将自身传进去。
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; }
- 此方法会做一些判断,以及判断传入的
ObserverWrapper
是否为null, 但是最终都会进入considerNotify
方法。下面我们看considerNotify
的源码部分:
private void considerNotify(ObserverWrapper observer) { //-----1----- if (!observer.mActive) { return; } //-----2----- if (!observer.shouldBeActive()) { observer.activeStateChanged(false); return; } //-----3----- if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; //-----4----- observer.mObserver.onChanged((T) mData); }
- 注释1处首先会判断是否处于Active状态,如果不是的话就return, 然后注释2处判断当前observer组件的对应状态是否是active, 如果不是的话就传入false执行
observer.activeStateChanged(false)
。 - 注释3处将当前的版本和observer中的值进行比较,如果不符合要求就return。其实查看源码,这里
mVersion
的值想要改变,只能通过livedata.setValue
或者livedata.postValue
才能改变。所以如果仅仅是调用livedata.observer
注册,而不调用这两个方法,是不会调用到注释4处真正的Observer回调的。
- 此方法会做一些判断,以及判断传入的
LiveData完整生命周期onCreate -> onDestory
- 到这里,大部分的源码分析工作就结束了,但是以上只是按照逻辑全局分析,并没有具体的从常见的生命周期
onCreate -> onDestory
分析,下面我们将从生命周期的onCreate -> onDestory
分析,如果仅仅调用开头例子中的livedata.observe
的话,不调用postValue
或者setValue
的话,源码究竟是如何控制逻辑的?这也是最开始让我疑惑的一个问题。 - 从上面的源码分析知道,当生命周期变化的时候都会依次执行
activeStateChanged(shouldBeActive()) -> dispatchingValue(this) -> considerNotify(initiator) -> observer.onChanged(data)
。下面我们按照生命周期开始一步一步分析。 onCreate
, 因为这个生命周期shouldBeActive()
为false, 所以在执行activeStateChanged
第一行的时候满足都为false, 就会被return掉。onStart
, 这个生命周期的shouldBeActive()
为true,在执行activeStateChanged
的时候将mActive
赋值true, 紧接着执行dispatchingValue -> considerNotify
, 在considerNotify
中,因为observer.mLastVersion >= mVersion
满足条件且都等于-1,所以这里会执行return。onResume
, 这个生命周期shouldBeActive()
为true,但是在执行activeStateChanged
第一行的时候,因为onStart
中讲到了,将mActive
已经赋值为true了,所以这里满足newActive == mActive
, 就也会执行return逻辑。onPause
, 和onResume
同理,也会执行return逻辑。onStop
,因为这个生命周期shouldBeActive()
为false, 会执行onInactive
方法,但是因为shouldBeActive()
为false, 所以不会执行后面的dispatchingValue
方法。onDestory
,在源码分析中我们知道, 如果处于这个生命周期的观察者是会被remove掉的
LiveData.setValue/postValue源码分析
- 上面我们分析了没有执行
postValue
方法时候的源码,都不会执行我们想要的Observer回调,现在我们来分析常用的setValue/postValue
时候的源码,源码如下:@MainThread protected void setValue(T value) { assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); } 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); } };
- 从上面
setValue
源码可以看出,首先判断当前的线程是不是主线程,如果不是就会抛出异常。然后将mVersion
加1,最后执行dispatchingValue(null)
方法。 postValue
方法就不限制主线程还是子线程,最终都会使用Handler机制,切换到主线程。执行mPostValueRunnable
。实际执行的还是setValue
。最终执行的也是dispatchValue(null)
。由此可见setValue
和postValue
的区别。下面我们看dispatchingValue(null)
是如何执行的: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(); ) { //-----1----- considerNotify(iterator.next().getValue()); if (mDispatchInvalidated) { break; } } } } while (mDispatchInvalidated); mDispatchingValue = false; } private void considerNotify(ObserverWrapper observer) { if (!observer.mActive) { return; } if (!observer.shouldBeActive()) { observer.activeStateChanged(false); return; } if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; //-----2----- observer.mObserver.onChanged((T) mData); }
- 上面传入的参数为null时候,会遍历
mObservers
执行注释1处的considerNotify
。 - 因为我们执行了
postValue
或者setValue
方法,所以mVersion
会加1,并且当时处于onResume
状态,所以注释2处直接会被执行。也就是说当我们的数据源一旦发生了变化,就会直接执行自定义的Observer回调,这样就保证了数据的即时性,并且兼顾了生命周期,这也就是LiveData组件的本质意义。
- 上面传入的参数为null时候,会遍历
- 从上面
Transformations.map()的源码分析
-
上一篇LiveData使用篇我们讲到了
Transformations.map()
的使用,这里我们粘贴一下上一篇的源码部分:class TestActivity : AppCompatActivity() { private val mutableLiveData = MutableLiveData<String>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mutableLiveData.observe(this, Observer { Log.d(TAG, "Changed1:$it") }) val mediatorLiveData: LiveData<String> = Transformations.map(mutableLiveData) { "$it+map" } mediatorLiveData.observe(this, Observer { Log.d(TAG, "Changed2:$it") }) } fun onTest(view: View) { mutableLiveData.postValue("LiveData") } }
- 这里我们直接看
map
的源码:
@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; }
- 这里涉及到了另一个
LiveData
的实现类MediatorLiveData
,此处调用了addSource
,然后在Observer
的回调中调用了自身的result.setValue(data)
方法,MediatorLiveData
的源码没多少,这里我们贴出来:
public class MediatorLiveData<T> extends MutableLiveData<T> { private SafeIterableMap<LiveData<?>, Source<?>> mSources = new SafeIterableMap<>(); @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(); } } @MainThread public <S> void removeSource(@NonNull LiveData<S> toRemote) { Source<?> source = mSources.remove(toRemote); if (source != null) { source.unplug(); } } @CallSuper @Override protected void onActive() { for (Map.Entry<LiveData<?>, Source<?>> source : mSources) { source.getValue().plug(); } } @CallSuper @Override protected void onInactive() { for (Map.Entry<LiveData<?>, Source<?>> source : mSources) { source.getValue().unplug(); } } 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); } } } }
- 上面我们看到其中有一个
SafeIterableMap
的成员变量mSources
, 在上一篇中说到,它以链表的形式存储的是待观察的LiveData。上面addSource
方法就是将LiveData对象存储的操作。在addSource
第一行我们看到有一个重要的类Source
,它里面封装了待观察的LiveData还有Observer对象。 - 下面我们一步一步分析一下上面
Transformations.map()
也就是MediatorLiveData
是如何实现观察数据的。 - 在生命周期为
onStart
的时候,前面分析过了会执行livedata.onActive()
方法,LiveData自身的onActive实现为空,但是我们这里是MediatorLiveData
,onActive的实现就不为空了,源码如下:
protected void onActive() { for (Map.Entry<LiveData<?>, Source<?>> source : mSources) { source.getValue().plug(); } } void plug() { mLiveData.observeForever(this); }
- 从上面可以看出,最终执行的是
mLiveData.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 != null && existing instanceof LiveData.LifecycleBoundObserver) { throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } wrapper.activeStateChanged(true); }
observeForever
和observer
从方法名字可以看出区别,observeForever
方法是永远绑定可观察的,它内部的AlwaysActiveObserver
类的shouldBeActive
永远为true,而observe
方法中的LifecycleBoundObserver
类的shouldBeActive
会判断生命周期。- 到这里执行完
observeForever
之后,就将上面测试代码中的mediatorLiveData
和mutableLiveData
仅仅的联系在了一起,这时候如果你debug就会发现,mutableLiveData
中这时候有两个ObserverWrapper
,一个是调用mediatorLiveData.observe
生成的LifecycleBoundObserver
,另一个是上面调用mediatorLiveData.addSource
时候,当生命周期执行到了onStart
时候,会执行source.plug()
,因为source
中存储的是mediatorLiveData
对象,实际上执行的是还是mediatorLiveData.observeForever
方法,所以第二个就是observeForever
中生成的AlwaysActiveObserver
。 - 这时候我们如果调用
mutableLiveData.postValue
的话,会遍历LiveData
中的mObservers
,首先会执行上面第一个LifecycleBoundObserver
的回调。 - 然后执行第二个
AlwaysActiveObserver
的回调,因为在mediatorLiveData
中的mSources
也存储着同样的Observer
回调,mutableLiveData
中的第二个ObserverWrapper
中的Observer
就是从mediatorLiveData.source.plug()
传进去的,我们再来看下Source源码进行分析:
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(); //-----1----- mObserver.onChanged(v); } } }
- 所以这里会执行上面注解1处的
mObserver.onChanged
,这个mObserver
就是我们调用Transformations.map(data)
时候,进而调用addSource
存入的,源码如下:
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) { //-----1----- result.setValue(mapFunction.apply(x)); } }); return result; }
- 所以也就会执行上面注释1处的
result.setValue
,这个result最终被返回,也就是我们测试代码中的mediatorLiveData
,调用result.setValue
的逻辑我们就不分析了,前面分析多次了。最终也就执行了mediatorLiveData
的数据监听回调。 - 当执行
onStop
生命周期的时候,会执行mediatorLiveData
的onInactive
方法将AlwaysActiveObserver
移除。 - 当执行
onDestory
生命周期的时候,在onStateChanged
也会执行removeObserver(mObserver)
,所以就不会有内存泄漏的风险。
- 这里我们直接看
总结
Transformations.switchMap
的源码部分和上面分析的Transformations.map
基本一样,就不赘述了。- LiveData真的是一个很好用的组件,既可以分开用,也可以组合其它的
ViewModel
组件使用。 - LiveData 具有生命周期感知能力,这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
- 当
LiveData
数据源发生变化的时候会立马回调,对UI进行更新,保证了数据的即时性。