写点什么

【AAC 系列三】深入理解架构组件,androidjetpack 视频

用户头像
Android架构
关注
发布于: 刚刚

}//ObserverWrapper.activeStateChangedactiveStateChanged(shouldBeActive());}


@Overrideboolean isAttachedTo(LifecycleOwner owner) {return mOwner == owner;}


@Overridevoid detachObserver() {mOwner.getLifecycle().removeObserver(this);}}


**ObserverWrapper?**:


private abstract class ObserverWrapper {final Observer<T> mObserver;boolean mActive;int mLastVersion = START_VERSION;


ObserverWrapper(Observer<T> observer) {mObserver = observer;}//是否是 active 状态 abstract boolean shouldBeActive();


boolean isAttachedTo(LifecycleOwner owner) {return false;}


void detachObserver() {}


void activeStateChanged(boolean newActive) {if (newActive == mActive) {return;}// immediately set active state, so we'd never dispatch anything to inactive// ownermActive = newActive;boolean wasInactive = LiveData.this.mActiveCount == 0;LiveData.this.mActiveCount += mActive ? 1 : -1;if (wasInactive && mActive) {onActive();}if (LiveData.this.mActiveCount == 0 && !mActive) {onInactive();}//如果 active 状态下,则发送数据更新通知 if (mActive) {dispatchingValue(this);}}}


仔细看下这两个类其实就能解答疑问了。


LifecycleBoundObserver 是 抽象类?ObserverWrapper 的子类,重写了?shouldBeActive() 方法,在 owner 处于至少是 STARTED 的状态下认为是 active 状态;并且它也实现了 GenericLifecycleObserver 接口,可以监听 lifecycle 回调,并且在?onStateChanged() 方法里处理了生命周期改变的事件,当接收到 DESTROYED 的事件会自动解除跟 owner 的绑定,并且将下个流程交给了 activeStateChanged() 。


到这里?【2.1】、【2.3】的问题已经有了答案:


【2.1】答:LifeData 在 observe 方法中用 LifecycleBoundObserver 包装了 observer ,并且通过它绑定了 owner。


【2.3】答:LifecycleBoundObserver 在?onStateChanged() 方法里处理了生命周期改变的事件,当接收到 DESTROYED 的事件会自动解除跟 owner 的绑定。


这里需要注意的是,当我们调用 observe() 注册后,由于绑定了 owner,所以在 active 的情况下,LiveData 如果有数据,则 Observer 会立马接受到该数据修改的通知。


此时的流程是:


observe-->


onStateChanged-->


activeStateChanged-->


dispat


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


chingValue-->


considerNotify-->


onChanged


可以称之为生命周期改变触发的流程,另外还有一种流程是 postValue&setValue 触发的流程,共两种。


2.3?activeStateChanged(boolean)

在 activeStateChanged() 方法里,处理了?onActive() 跟?onInactive() 回调的相关逻辑处理,并且调用了 dispatchingValue(this) 。(MediatorLiveData 用到了 onActive() 跟 onInactive() 有兴趣自行了解,这里不展开)


接下去探索 dispatchingValue


2.4?dispatchingValue(ObserverWrapper) 分析

private void dispatchingValue(@Nullable ObserverWrapper initiator) {//如果正在分发则直接返回 if (mDispatchingValue) {//标记分发失效 mDispatchInvalidated = true;return;}//标记分发开始 mDispatchingValue = true;do {mDispatchInvalidated = false;//生命周期改变调用的方法 initiator 不为 nullif (initiator != null) {considerNotify(initiator);initiator = null;} else {//postValue/setValue 方法调用 传递的 initiator 为 nullfor (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);//标记分发结束 mDispatchingValue = false;}


considerNotify(ObserverWrapper)? 方法:


private void considerNotify(ObserverWrapper observer) {//检查状态 确保不会分发给 inactive 的 observerif (!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;}//setValue 会增加 version ,初始 version 为-1if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;//noinspection uncheckedobserver.mObserver.onChanged((T) mData);}


可以看到?dispatchingValue 正是分发事件逻辑的处理方法,而 considerNotify 方法则确保了只将最新的数据分发给 active 状态下的 Observer?。


另外也可以看到 LiveData 引入了版本管理来管理数据 (mData)以确保发送的数据总是最新的。(具体不多讲)


dispatchingValue?这里分两种情况:


  1. ObserverWrapper 不为 null

  2. ObserverWrapper 为 null


需要着重讲一下。


2.4.1 ObserverWrapper 不为 null 的情况

上面提到过,LifecycleBoundObserver.onStateChanged 方法里调用了?activeStateChanged ,而该方法调用 dispatchingValue(this);传入了 this ,也就是?LifecycleBoundObserver ,这时候不为 null 。


也就是说生命周期改变触发的流程就是这种情况,这种情况下,只会通知跟该 Owner 绑定的 Observer。


2.4.2?ObserverWrapper 为 null 的情况

上面我也提前说了,除了生命周期改变触发的流程外,还有 postValue&setValue 流程,来看下这俩方法。


private final Runnable mPostValueRunnable = new Runnable() {@Overridepublic void run() {Object newValue;synchronized (mDataLock) {newValue = mPendingData;mPendingData = NOT_SET;}//noinspection unchecked//调用 setValuesetValue((T) newValue);}};


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


@MainThreadprotected void setValue(T value) {//必须在主线程调用 否则会 crashassertMainThread("setValue");mVersion++;//增加版本号 mData = value;//传入了 nulldispatchingValue(null);}


LiveData 的?postValue 方法其实就是把操作 post 到主线程,最后调用的还是 setValue 方法,注意 setValue 必须是在主线程调用。


并且可以看到** setValue 方法调用了 dispatchingValue 方法,并传入了 null ,这个时候的流程则会通知 active 的 mObservers**。


到这里之前的剩下的所有疑问也都可以解答了。


LiveData 的两个流程都会走到?dispatchingValue 处理分发通知逻辑,并且在分发通知前会判断 owner 的状态,再加上 LiveData 本身内部的版本管理,确保了只会发送最新的数据给 active 状态下的 Observer


**注意:**LiveData 对同时多次修改数据做了处理,如果同时多次修改,只会修改为最新的数据。


3. 图解 LiveData


3.1 LiveData 类图

再看一遍类图,回顾一下:



(图 2.LiveData 类图)

3.2 LiveData 流程图

Lifecycle 改变触发流程:



(图 3.Lifecycle 改变触发流程图)


Lifecycle postValue/setValue 触发流程:



(图 4.setValue 改变触发流程图)


4. LiveData tips and recipes

LiveData 还有很多其他相关知识,这里列举一些,更多实践可以看一下【7.6】。


4.1 Sticky Event

LiveData 被订阅时,如果之前已经更改过数据,并且当前 owner 为 active 的状态,activeStateChanged() 会被调用,也即会立马通知到 Observer ,这样其实就类似 EventBus 的 sticky event 的功能,需要注意的是,很多时候我们并不需要该功能。具体可以看一下【7.6】的处理。


4.2 AlwaysActiveObserver

默认情况下,LiveData 会跟 LicycleOwner 绑定,只在 active 状态下更新,如若想要不管在什么状态下都能接收到数据的更改通知的话,怎么办?这时候需要使用 AlwaysActiveObserver ,改调用 observe 方法为调用 LiveData.observeForever(Observer) 方法即可。


4.3?MediatorLiveData

LiveData 还有一个子类是?MediatorLiveData,它允许我们合并多个 LiveData,任何一个 LiveData 有更新就会发送通知。比如我们的数据来源有两个,一个数据库一个网络,这时候我们会有两个 DataSource,也就是两个 LiveData,这个时候我们可以使用 MediatorLiveData 来 merge 这两个 LiveData。


4.4?Transformations

Transformations 允许我们把一个 LiveData 进行处理,变化成另外一个 LiveData,目前支持 map 跟 switchMap 两个方法,跟 RxJava 的操作类似。


比如,用 map 把一个 String 类型的 LiveData 转换成 Integer 类型:


Transformations.map(liveString, new Function<String, Integer>() {@Overridepublic Integer apply(final String input) {return Integer.valueOf(input);

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
【AAC 系列三】深入理解架构组件,androidjetpack视频