关于LiveData LiveData
是一种可观察的数据持有类,下面是常用的写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class DataViewModel (application: Application) : AndroidViewModel(application) { val dataSource: LiveData<String> = MutableLiveData() fun postValue (text: String ? = "Hello World" ) { (dataSource as MutableLiveData).postValue(text) } } viewModel.dataSource.observe(this , object : Observer<String> { override fun onChanged (t: String ?) { println("onChange: ${t} " ) } })
一般情况下,LiveData
和 ViewModel
都是搭配使用的,可以在 Activity
和 Fragment
范围内提供复用,并处理因配置发生改变,而重建的情况。
关于 ViewModel
更详细的理解,可以阅读之前的文章:Jetpack中的ViewModel
如果了解过 RxJava 的同学,对这种观察者 的设计模式应该有点了解,LiveData
也是同样的思想,不过和 RxJava 不同的是:LiveData
使用 Lifecycle
将数据源和 Activity
和 Fragment
的生命周期结合起来,避免内存泄漏等情况。这个特性也是本文的重点。
关于 Lifecycle 更详细的理解,可以阅读之前的文章:Jetpack中的Lifecycle
建议在阅读以下内容时,先理解下 Lifecycle
,因为 LiveData
能感应 Activity
和 Fragment
的生命周期就是基于 Lifecycle
实现的。
源码解析 各个模块的作用 在理解源码之前,我们先理清组成 LiveData
各个模块的作用。
LiveData LiveData
表示一个可观察的数据源。在 LiveData
的设计中,它被设计为一个纯粹的数据源,对外只提供了:
observe(LifecycleOwner,Observer)
表示注册一个观察者(Observer
),这里同时需要提供一个 LifecycleOwner
用于提供 Lifecycle
observeForever(Observer)
功能和 observe(LifecycleOwner,Observer)
类似,但缺少感应生命周期的功能
removeObserver(Observer) 和 removeObservers(LifecycleOwner)
表示删除观察者,后者则是删除同个 LifecycleOwner
范围的 Observer
getValue()
表示获取当前值
hasObservers()
表示是否存在 Observer
hasActiveObservers()
表示是否存在活动的 Observer
,至于怎么去定义为活动的,后面会讲到
LiveData
是一个纯粹的数据源,不包含添加数据的公开 API,只能通过使用 MutableLiveData
去添加数据
这是一种不错的设计理念,单个组件功能越纯粹,代码的耦合度就越低。
Observer Observer
表示观察者,响应数据发生变化。API 也非常简单:onChange(T)
,这里需要注意的是:onChange()
中数据可以为 NULL
,这和 RxJava2
的设计是不一样的,这个很难说,哪个设计更优。但根据 JakeWharton 的回答是:It’s not RxJava’s choice, it’s in the reactive streams spec.
关于 RxJava2
不能传递 NULL
的讨论,可以参考这篇文章
observe 调用 LiveData.observe(LifecycleOwner,Observer)
去注册一个订阅者:
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 @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); } @Override boolean isAttachedTo (LifecycleOwner owner) { return mOwner = = owner; }
LifecycleBoundObserver
实现了 GenericLifecycleObserver
接口,用于响应 Activity
和 Fragment
的生命周期
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 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) { 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 ); } } 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 ; } 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 ); } } }
当调用 observe()
会根据当前是否为活跃状态,分发当前值。
postValue 和 setValue 当在非主线程调用时,使用 postValue()
,相关源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 protected void postValue (T value) { boolean postTask; synchronized (mDataLock) { postTask = mPendingData == NOT_SET; mPendingData = value; } if (!postTask) { return ; } ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); }
这里需要注意的是,当分发数据的任务还没结束时,多次调用 postValue
只会分发最后一次的值,同一时间只会存在一个 PostValueRunnable
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 private final Runnable mPostValueRunnable = new Runnable () { @Override public void run () { Object newValue; synchronized (mDataLock) { newValue = mPendingData; mPendingData = NOT_SET; } setValue((T) newValue); } }; @MainThread protected void setValue (T value) { assertMainThread("setValue" ); mVersion++; mData = value; 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(); ) { considerNotify(iterator.next().getValue()); if (mDispatchInvalidated) { break ; } } } } while (mDispatchInvalidated); mDispatchingValue = false ; }
如果有阅读过 Jetpack中的Lifecycle 这篇文章的话,可以很快看出,分发值的处理和 Lifecycle
有类似的地方,即在分发过程中,有新的值开始分发这种 case,都是采用中断当前的分发,推迟到下一次遍历时,分发新的值。
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 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); }
需要注意的是,setValue
和 postValue
方法都是 protected
,所以当我们想实现一个 LiveData 时,需要使用 MutableLiveData,源码很简单,就是将这两个方法修改为 public
。
这种实现思路有利于数据的不可变性。上游使用 MutableLiveData 分发数据,下游使用 LiveData 消费数据。
如果使用过 RxJava 类似库的同学可能会觉得跟 LiveData 很像,同样是监听者模式。不一样的是,RxJava 提供了很多操作符,类似 map
、zip
等,还有线程调度的 observeOn
和 subscribeOn
。LiveData 没有线程调度的功能,它数据分发只在主线程上进行,没有线程锁等开销。除此之前,LiveData 只提供了 map
和 switchMap
的实现,但提供了 MediatorLiveData
去实现自己需要的操作符。
Transformations 中有 map
和 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 @MainThread 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; } @MainThread 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; }
MediatorLiveData 可以监听多个 LiveData,这里我们简单看下它的源码:
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 @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); } } }
总结 LiveData 可以算是 RxJava 的简化版本,它最大的好处就是和 Lifecycle 结合起来使用,不需要手动处理监听。第二个是,将数据分发操作封闭在主线程,减少线程同步锁的损耗,更适合 Android 日常开发场景。