理解《LifeCycle核心原理》的分析,LiveData的分析会比较快速一点。
1)基本使用
xxxViewModel.xxxLiveData.observe(this, (this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
// 业务逻辑
}
});
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
其中,第一个参数是被观察者,比如Activity/Fragment;第二个参数是观察者,自定义实现即可。
2)原理分析
- LiveData为何可以感知生命周期?
- LiveData如何做到仅在页面Active的情况下,进行回调的?
- LiveData的setValue与postValue,及其区别
2.1、LiveData为何可以感知生命周期?
首先,需要看一下LiveData的observe方法的源码:
- LiveData
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {// LiveData已经为我们规避了该状态
// ignore
return;
}
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;
}
// #1 核心代码
owner.getLifecycle().addObserver(wrapper);
}
先不用看其他部分的代码,仅看一下#1出的核心代码。
结论:LiveData依托于被观察者(Activity/Fragment),向其注册观察者实现生命周期感知。
LiveData向LifecycleOwner(Activity/Fragment)的LifecycleRegistry对象添加了观察者。通过这个观察者,就可以持续收到页面生命周期的变化【触发观察者的onStateChanged方法的调用】。NOTE:Jetpack为我们提供的观察者均实现了LifecycleEventObserver接口,该接口包含了onStateChanged方法,所以对于不同的观察者,其onStateChanged方法的实现是不一样的,可查看ReflectiveGenericLifecycleObserver(通过注解感知生命周期)与LifecycleBoundObserver(LiveData自定义Observer)关于onStateChanged的实现。
- ReflectiveGenericLifecycleObserver(通过注解感知生命周期) - 反射调用注解方法
- LifecycleBoundObserver(LiveData自定义Observer) - 触发postValue/setValue方法调用
这里LiveData的做法,与我们在《LifeCycle核心原理》中的示例做法是一致的,所以想要感知生命周期,向页面的LifecycleRegistry对象添加了观察者即可。
可以感知生命周期的原理,可查看《LifeCycle核心原理》的分析。
2)LiveData如何做到仅在页面Active的情况下,进行回调的?
这里我们直接查看LifecycleBoundObserver即可得到答案。
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {// 至少大于STARTED,也就是RESUMED状态
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {// 页面销毁的时候,LiveData主动移除观察者
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());// 在页面是active的前提下,触发postValue/setValue的调用
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
3)LiveData的setValue/postValue调用
- LifecycleBoundObserver的父类:ObserverWrapper
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
......
if (mActive) {
dispatchingValue(this);// 触发LiveData的dispatchingValue方法调用
}
}
- LiveData
void dispatchingValue(@Nullable ObserverWrapper initiator) {
......
do {
mDispatchInvalidated = false;
if (initiator != null) {// onStateChanged的时候走这里
considerNotify(initiator);
initiator = null;
} else {// setValue的时候,走这里
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {// mObservers是LiveData的所有观察者
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
无论走哪一个分支,最终都调用了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;
}
// mVersion++;时机是setvalue
// mVersion的作用是在页面InActive的场景下,比如单独线程每个1秒发送一次请求,那么当页面Active的时候,仅响应最后一个请求【因为响应完,observer.mLastVersion = mVersion;了】
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);// 观察者回调
}
附:
- LiveData
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
其中,mPostValueRunnable如下:
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
可以看到postValue最终也是切换到主线程,调用了setValue方法。
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
本文详细剖析了LiveData的核心原理,讲解了如何通过观察者感知Activity/Fragment生命周期,以及LiveData如何在页面活跃时仅回调观察者。重点介绍了setValue与postValue的区别,以及观察者在不同状态下的行为。
4739

被折叠的 条评论
为什么被折叠?



