LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 activity、fragment 或 service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
使用 LiveData 的优势
使用 LiveData 具有以下优势:
- 确保界面符合数据状态LiveData 遵循观察者模式。当底层数据发生变化时,LiveData 会通知Observer对象。您可以整合代码以在这些Observer对象中更新界面。这样一来,您无需在每次应用数据发生变化时更新界面,因为观察者会替您完成更新。
- 不会发生内存泄漏观察者会绑定到Lifecycle对象,并在其关联的生命周期遭到销毁后进行自我清理。
- 不会因 Activity 停止而导致崩溃如果观察者的生命周期处于非活跃状态(如返回堆栈中的 activity),它便不会接收任何 LiveData 事件。
- 不再需要手动处理生命周期界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
- 数据始终保持最新状态如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
- 适当的配置更改如果由于配置更改(如设备旋转)而重新创建了 activity 或 fragment,它会立即接收最新的可用数据。
- 共享资源您可以使用单例模式扩展LiveData对象以封装系统服务,以便在应用中共享它们。LiveData对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察LiveData对象。如需了解详情,请参阅扩展 LiveData。
LiveData的几种用法
声明一个LiveData
我们发现LiveData是一个抽象类,它的默认实现子类是MutableLiveData,但是看源码他们没有区别~唯一区别就是set和post方法公开了,之所以这么设计,是考虑到单一开闭原则,只有拿到 MutableLiveData 对象才可以发送消息,LiveData 对象只能接收消息,避免拿到 LiveData 对象时既能发消息也能收消息的混乱使用。
//1.声明一个MutableLiveData
val data = MutableLiveData("Test")fun main(){//2.监听数据源变化data.observe(this){ data->//...do somethig}
}
组合多个LiveData统一观察
当我们有多个LiveData时候,某些场景下我们想统一监听,那这个时候我们可以使用MediatorLiveData来对多个LiveData进行统一监听。
//创建两个长得差不多的LiveData对象
LiveData<Integer> liveData1 = new MutableLiveData();
LiveData<Integer> liveData2 = new MutableLiveData();//再创建一个聚合类MediatorLiveDataMediatorLiveData<Integer> liveDataMerger = new MediatorLiveData<>();//分别把上面创建LiveData 添加进来。
liveDataMerger.addSource(liveData1, observer);
liveDataMerger.addSource(liveData2, observer);Observer observer = new Observer<Integer>() {@Overridepublic void onChanged(@Nullable Integer s) {titleTextView.setText(s);}
//一旦liveData或liveData发送了新的数据 ,observer便能观察的到,以便 统一处理更新UI
转换数据
比如我们希望对一个Int值的LiveData在监听里变成String,那么我们可以用到Transformations.map 操作符进行该操作
MutableLiveData<Integer> data = new MutableLiveData<>();//数据转换
LiveData<String> transformData = Transformations.map(data, input -> String.valueOf(input));
//使用转换后生成的transformData去观察数据
transformData.observe( this, output -> {});//使用原始的livedata发送数据
data.setValue(10);
LiveData实现原理
观察者生命周期
observe方法负责建立生命周期绑定关系,并注册观察者,如下所示:
@MainThreadpublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {assertMainThread("observe");if (owner.getLifecycle().getCurrentState() == DESTROYED) {// ignorereturn;}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);}
LiveData将Observer对象加入mObservers中,数据变更时会遍历这个Map分发最新数据。LifecycleBoundObserver类负责监听应用组件的生命周期变化,如下所示:
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {@NonNullfinal LifecycleOwner mOwner;LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {super(observer);mOwner = owner;}@Overrideboolean shouldBeActive() {return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}@Overridepublic 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();}}@Overrideboolean isAttachedTo(LifecycleOwner owner) {return mOwner == owner;}@Overridevoid detachObserver() {mOwner.getLifecycle().removeObserver(this);}}
如onStateChanged方法所示,Lifecycle.State为DESTROYED时,移除观察者,其他情况则更改观察者的状态。
数据分发
有两个方法触发数据分发,一个是setValue,在数据变更时触发;一个是ObserverWrapper的activeStateChanged方法,在生命周期变更是触发(例如,从后台切换到前台),就是这个方法确保了应用组件的数据始终是最新的。如下所示:
private abstract class ObserverWrapper {final Observer<? super T> mObserver;boolean mActive;int mLastVersion = START_VERSION;ObserverWrapper(Observer<? super T> observer) {mObserver = observer;}void activeStateChanged(boolean newActive) {if (newActive == mActive) {return;}// immediately set active state, so we'd never dispatch anything to inactive// ownermActive = newActive;changeActiveCounter(mActive ? 1 : -1);if (mActive) {dispatchingValue(this);}}}@MainThreadprotected void setValue(T value) {assertMainThread("setValue");mVersion++;mData = value;dispatchingValue(null);}@SuppressWarnings("WeakerAccess") /* synthetic access */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;}@SuppressWarnings("unchecked")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);}
considerNotify方法负责实际的数据分发,如果观察者处于非激活态则不分发数据,否则有最新的数据就会分发到观察者,即调用onChanged((T) mData)方法。
本文主要讲解framework通信机制中的LiveData的用法以及原理,更多有关framework通信技术可以参考《framework全家桶手册》点击可查看详细内容。