- 通过 setValue()/postValue() 更新数据的处理流程是如何?
- 生命周期变化后数据处理流程是怎么样的?
同时提前看下我整理的 LiveData UML 图,对 LiveData 有个整体的了解,后续的涉及到的类都在这里了,有助于理解。
(图1.LiveData 类图)
OK, here we go!
2.1 LiveData.observe()
LiveData 的使用流程从 observe()
开始,咱们尝试从 observe()
方法 开始分析:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
//如果是 DESTROYED 的状态则忽略
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//把 Observer 用 LifecycleBoundObserver 包装起来
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//缓存起来
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
//如果已经 observe 过 并且两次的 owner 不同则报错
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException(“Cannot add the same observer”
- " with different lifecycles");
}
if (existing != null) {
return;
}
//绑定 owner
owner.getLifecycle().addObserver(wrapper);
}
可以看到 observe 方法里把我们传递的 observer 用 LifecycleBoundObserver
包装了起来,并且存入了 mObservers
,并且跟 owner 进行了关联。
并且做了两个特殊处理:
- 忽视处于 DESTROYED 的 owner 的注册行为;
- 将一个 Observer 同时绑定两个 owner 的行为视为非法操作,也即一个 Observer 只能绑定一个 owner,而 owner 可以有多个 Observer;
这里出现了几个新的类 LifecycleBoundObserver 、ObserverWrapper 来看看。
2.2 LifecycleBoundObserver
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
// 判断 owner 当前的状态是否是至少 STARTED
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
//生命周期改变,如果是 DESTROYED 就自动解除
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//ObserverWrapper.activeStateChanged
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
**ObserverWrapper **:
private abstract class ObserverWrapper {
final Observer mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer 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
// owner
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();
}
//如果 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–>
dispatchingValue–>
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 不为 null
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//postValue/setValue 方法调用 传递的 initiator 为 null
for (Iterator<Map.Entry<Observer, 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 的 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;
}
//setValue 会增加 version ,初始 version 为-1
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
可以看到 dispatchingValue 正是分发事件逻辑的处理方法,而 considerNotify 方法则确保了只将最新的数据分发给 active 状态下的 Observer 。
另外也可以看到 LiveData 引入了版本管理来管理数据 (mData)以确保发送的数据总是最新的。(具体不多讲)
dispatchingValue 这里分两种情况:
- ObserverWrapper 不为 null
- 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() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
//调用 setValue
setValue((T) newValue);
}
};
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
@MainThread
protected void setValue(T value) {
//必须在主线程调用 否则会 crash
assertMainThread(“setValue”);
mVersion++;//增加版本号
mData = value;
//传入了 null
dispatchingValue(null);
}
LiveData 的 postValue 方法其实就是把操作 post 到主线程,最后调用的还是 setValue 方法,注意 setValue 必须是在主线程调用。
并且可以看到** setValue 方法调用了 dispatchingValue 方法,并传入了 null ,这个时候的流程则会通知 active 的mObservers**。
到这里之前的剩下的所有疑问也都可以解答了。
LiveData 的两个流程都会走到 dispatchingValue 处理分发通知逻辑,并且在分发通知前会判断 owner 的状态,再加上 LiveData 本身内部的版本管理,确保了只会发送最新的数据给 active 状态下的 Observer。
**注意:**LiveData 对同时多次修改数据做了处理,如果同时多次修改,只会修改为最新的数据。
3. 图解 LiveData
3.1 LiveData 类图
再看一遍类图,回顾一下:
3.2 LiveData 流程图
Lifecycle 改变触发流程:
(图3.Lifecycle 改变触发流程图)
Lifecycle postValue/setValue 触发流程:
(图4.setValue 改变触发流程图)
4. LiveData tips and recipes
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
…(img-s33zz1P0-1715796123660)]
[外链图片转存中…(img-NEIWLJD6-1715796123661)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!