提纲
- 什么是LivaData
- LiveData衍生类
- LiveData核心方法
- LiveData事件分发实现原理
什么是LiveData
LiveData 组件是 Jetpack 新推出的基于观察者的消息订阅/分发组件,具有宿主(Activity、Fragment)生命周期感知能力,这种感知能力可确保 LiveData 仅分发消息给处于活跃状态的观察者,即只有处于活跃状态的观察者才能收到消息。
活跃状态:通常情况下等于 Observer 所在宿主处于 started,resumed 状态,如果使用 observeForever 注册的,则一直处于活跃状态。
LiveData 的消息分发机制,是以往的 Handler、EventBus、RxjavaBus 无法比拟的,它们不会顾及当前页面是否可见,一股脑的有消息就转发。导致即便应用在后台页面不可见的情况下还在做一些无用的工作抢占资源。举个例子,细心的同学可以发现微信消息列表是在页面可见状态时才会更新列表最新信息的。
LiveData 的出现解决了以往使用 callback 回调可能带来的NPE,生命周期越界,后台任务抢占资源等问题。
LiveData的优势
确保界面符合数据状态LiveData 遵循观察者模式。当生命周期状态发生变化时,LiveData 会通知 [Observer
]对象并把最新数据派发给它。观察者可以在收到onChanged
事件时更新界面,而不是在每次数据发生更改时立即更新界面。
不再需要手动处理生命周期只需要观察相关数据,不用手动停止或恢复观察。LiveData 会自动管理Observer的反注册,因为它能感知宿主生命周期的变化,并在宿主生命周期的onDestory
自动进行反注册。因此使用LiveData
做消息分发不会发生内存泄漏
数据始终保持最新状态如果宿主的生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
支持黏性事件的分发即先发送一条数据,后注册一个观察者,默认是能够收到之前发送的那条数据的
共享资源我们可以使用单例模式拓展 LiveData
,实现全局的消息分发总线。
LiveData 实现原理
黏性消息分发流程,即新注册的 observer 也能接收到前面发送的最后一条数据。原因就在于LiveData 每次发送一条数据它的 mVersion 都会 +1。但是新注册的 Observer 的 lastVersion=0 ,图中的 considerNotify 方法就会把前面发送的数据分发给新注册的 Observer 了。
LiveData 注册观察者触发消息分发流程原理分析
observe 注册时,可以主动跟宿主生命周期绑定,不用反注册:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { assertMainThread("observe"); 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"); } owner.getLifecycle().addObserver(wrapper); }
|
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
| class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver { LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) { super(observer); }
@Override boolean shouldBeActive() { return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); }
@Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } activeStateChanged(shouldBeActive()); } }
|
ObserverWrapper 状态变更后,如果观察者处于活跃状态会触发数据的分发流程:
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
| abstract class ObserverWrapper{ final Observer<? super T> mObserver; boolean mActive; int mLastVersion = START_VERSION 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); } } }
|
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
| 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; }
|
considerNotify 数据真正分发的地方,需要满足三个套件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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); }
|
普通消息分发流程。即调用 postValue,setValue 才会触发消息的分发:
我们经常会使用observer()
,observeForever()
去注册观察者,它俩有什么区别呢?
- **observer()**:不需要手动反注册,并且宿主不可见时收不到消息,当宿主恢复可见时,会立刻收到最新的数据;
- **observeForever()**:需要自行手动反注册,并且无论宿主是否可见,都能够收到消息;
- 可以充分利用 onActive() 方法被激活的时机,来实现一些数据懒加载的功能。