写点什么

【Jetpack 篇】LiveData 取代 EventBus,2021 年 Android 知识体系总结

用户头像
Android架构
关注
发布于: 11 小时前

LiveData 遵循观察者模式,它的厉害之处不仅在于数据有变化时能及时通知 UI,而且 LiveData 能够感知 Activity、Fragment 等组件的生命周期,随组件销毁而自动销毁,不用开发者去操心,极大的减少了内存泄漏的可能。


那 LiveData 是如何通信并且感知组件的生命周期的呢?

LiveData 的通信原理

从上面例子可以知道 LiveData 的核心主要在于这两步,liveData.observe()以及 liveData.postValue(),一个是注册观察者,一个是发送通知。那么下面的解析就将这两个函数作为切入点。

1.LiveData.observe()

从 liveData.observe()跟踪


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


进去:


LiveData.java


private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =new SafeIterableMap<>();


......


@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);}


observe 方法传有两个参数 LifecycleOwner 和 Observer,LifecycleOwner 是一个具有 Android 生命周期的类,一般传入的是 Activity 和 Fragment,Observer 是一个接口,内部存在 void onChanged(T t)方法。


? 第一部分: observe 内部一开始就存在一个生命周期的判断,


if (owner.getLifecycle().getCurrentState() == DESTROYED) {return;}


当组件生命周期已经 Destroy 了,也就没有必要再继续走下去,则直接 return。在这里,LiveData 对生命周期的感知也就慢慢显现出来了。


? 第二部分: 首先以 LifecycleOwner 和 Observer 作为参数创建了一个 LifecycleBoundObserver 对象,接着以 Observer 为 key,新创建的 LifecycleBoundObserver 为 value,存储到 mObservers 这个 map 中。在后面 LiveData postValue 中会遍历出该 map 的 value 值 ObserverWrapper,获取组件生命周期的状态,已此状态来决定分不分发通知(这部分详情见“第二小节 postValue()”)


那 LifecycleBoundObserver 是什么?


class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {@NonNullfinal LifecycleOwner mOwner;


LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {super(observer);mOwner = owner;}


.......}


从源码可以看到,LifecycleBoundObserver 继承 ObserverWrapper 并且实现了 LifecycleEventObserver 的接口,LifecycleEventObserver 是监听组件生命周期更改并将其分派给接收方的一个接口,而在 LifecycleBoundObserver 的构造函数中将 observer 传给了父类 ObserverWrapper。LifecycleBoundObserver 其实只是包裹着 LifecycleOwner 和 Observer 得一个类,其中的实现有点代理模式的味道。


? 第三部分: owner.getLifecycle().addObserver(wrapper)将新创建的 LifecycleBoundObserver 添加到 Lifecycle 中,也就是说这个时候观察者注册成功,当 LifecycleOwner 也就是组件的状态发生改变时,也会通知到所匹配的 observer。


到这里,UI 层viewModel.liveData.observe(this, object:Observer<String> { override fun onChanged(value: String) {} })注册观察者的内部解析也就大致清楚了。

2.postValue()

liveData.postValue()是作为一个发射方来通知数据改变,其内部又做了哪些工作?接下来就一探究竟。直接从 postValue 中最核心的部分在于将参数 value 赋值给了一个全局变量源码开始:


protected void postValue(T value) {boolean postTask;synchronized (mDataLock) {postTask = mPendingData == NOT_SET;mPendingData = value;}if (!postTask) {return;}ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}


postValue 中首先将参数 value 赋值给了一个全局变量 mPendingData,它的初始值为一个空对象,而 mPendingData 只是作为一个中间媒介来存储 value 的值,在后续的操作中会用到,我们就暂时先记住它。


在最后就是一个将线程切换到主线程的操作,主要看 mPostValueRunnable 的实现:


private final Runnable mPostValueRunnable = new Runnable() {@SuppressWarnings("unchecked")@Overridepublic void run() {Object newValue;synchronized (mDataLock) {newValue = mPendingData;mPendingData = NOT_SET;}setValue((T) newValue);}};


在 Runnable 中,mPendingData 赋值给了临时变量 newValue,最后调用了 setValue()方法。我们都知道 LiveData 发送通知可以使用 PostValue 或者 SetValue,而他两的区别就在于,PostValue 可以在任意线程中调用,而 SetValue 只能在主线程中,因为 PostValue 多了一步上面切换主线程的操作。


OK,接下来就是 PostValue/SetValue 最核心的部分。


@MainThreadprotected 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;}


在 setValue 中,参数 value 将值赋给了一个全局变量 mData,而这个 mData 最后将通过 mObserver.onChanged((T) mData);将需要修改的 value 值分发给了 UI。最后调用传入一个 null 调用 dispatchingValue 方法。


由于 dispatchingValue 里的参数为 null,也就顺理成章的走到了**? 第二部分**。else 一进入就是迭代器在遍历 mObservers,而 mObservers 在第一小节“1.LiveData.observe()”中说得很清楚,它作为一个 map,存储了 Observer 和 ObserverWrapper。通过遍历,将每个观察者所匹配的 ObserverWrapper 作为参数传给了 considerNotify()方法。


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()中,先通过 observer 来获取组件生命周期的状态,如果处于非活动状态,则拒绝发起通知。在该方法的最后, observer.mObserver.onChanged((T) mData),是不是很熟悉,这就是 UI 层一开始就实现的接口,而就在这找到了最后的发送方。

小结

LiveData 是如何通信的?就一句话,UI 层注册好一个 observer,就存储到一个存储着观察者的 map 中,直到开发者调用 postValue/setValue 则遍历该 map,分发出 observer 的 onChanged 通知,在此过程中,都会监听组件的生命周期,并以此来判断所匹配的组件是否处于活动状态,否则直接 return。

三、LiveData 的粘性事件

发送消息事件早于注册事件,依然能够接收到消息的通知的为粘性事件


即先调用 LiveData 的 postValue/setValue 方法,后注册 observe,依然能够收到 onChange()的通知。从上面的分析可以知道,LiveData 最后 postValue 是将通知分发给已经注册好的观察者,而 LiveData 的粘性事件是先发送后注册,那为什么也能够收到通知呢?是哪里分发了 onChange()?


我们知道粘性事件是注册后就收到了通知,那么就可以以 liveData.observe()为切入点,康康源码中的实现。


@MainThreadpublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {......owner.getLifecycle().addObserver(wrapper);}


LiveData 注册观察者,最核心在于owner.getLifecycle().addObserver(wrapper);addObserver 是用来添加一个 LifecycleObserver,当 LifecycleOwner 改变状态时,它会被通知。例如,如果 LifecycleOwner 处于 State#STARTED 状态,给定的观察者将收到 Event#ON_CREATE、Event#ON_START 事件。


而我们跟踪到它的实现类里面,


public class LifecycleRegistry extends Lifecycle {......@Overridepublic void addObserver(@NonNull LifecycleObserver observer) {State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);


if (previous != null) {return;}LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {// it is null we should be destroyed. Fallback quicklyreturn;}


boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;State targetState = calculateTargetState(observer);mAddingObserverCounter++;while ((statefulObserver.mState.compareTo(targetState) < 0&& mObserverMap.contains(observer))) {pushParentState(statefulObserver.mState);? 切入点 statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));popParentState();// mState / subling may have been changed recalculatetargetState = calculateTargetState(observer);}

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
【Jetpack篇】LiveData取代EventBus,2021年Android知识体系总结