LiveData的原理:使用了观察者设计模式,但是这个观察者是跟生命周期拥有者(Activity或Fragment)绑定了生命周期的,想要了解LiveData的原理,还要先理解Lifecycle的原理,因为里面表面是LiveData和Observer建立观察者模式,但实际最终还是LifecycleOwner和LifecycleObserver建立的观察者模式。
我这里先梳理一个各函数的流程:
注册的流程:
LiveData(observe)--->LifecycleRegistry(addObserver)--->ObserverWithState(dispatchEvent)--->LifecycleBoundObserver(onStateChanged)--->ObserverWrapper (activeStateChanged)--->LiveData(dispatchingValue)--->LiveData(considerNotify)--->Observer(onChanged)最终就到了数据的onChange回调了。
发送数据的流程:
LiveData(setValue)--->LiveData(dispatchingValue)--->LiveData(considerNotify)--->Observer(onChanged)
一、LiveData 核心方法:
1、LiveData 公开(public)方法
T getValue()
//返回当前值。请注意,在后台线程上调用此方法不能保证将接收到最新的值集。
boolean hasActiveObservers()
//如果此LiveData具有活动的观察者,则返回true。
boolean hasObservers()
//如果此LiveData具有观察者,则返回true。
void observe(LifecycleOwner owner, Observer<T> observer)
//(注册和宿主生命周期关联的观察者)将给定的观察者添加到给定所有者的生存期内的观察者列表中。
void observeForever(Observer<T> observer)
//(注册观察者,不会反注册,需自行维护)将给定的观察者添加到观察者列表中。
void removeObserver(Observer<T> observer)
//从观察者列表中删除给定的观察者。
void removeObservers(LifecycleOwner owner)
//删除所有与给定绑定的观察者LifecycleOwner。
2、LiveData 受保护(protected)方法
void onActive()
//(当且仅当有一个活跃的观察者时会触发)当活动观察者的数量从0变为1时调用。
void onInactive()
//(不存在活跃的观察者时会触发)当活动观察者的数量从1变为0时调用。
//这并不意味着没有观察者,可能仍然有观察者,但是它们的生命周期状态不是STARTED或RESUMED (如后退堆栈中的“Avtivity”)。
//您可以通过来检查是否有观察者hasObservers()。
void postValue(T value)
//(和setValue一样。不受线程环境限制,)将任务发布到主线程以设置给定值。
void setValue(T value)
//(发送数据,没有活跃的观察者时不分发。只能在主线程。)设置值。
二、LiveData 原理解析:
1、observe订阅源码分析
LiveData 注册观察者触发消息分发流程原理分析
1.1首先看看observe方法源码
observe 注册时,可以主动跟宿主生命周期绑定,不用反注册:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//1. 断言,这个方法只能在主线程调用(如果不在主线程注册会抛IllegalStateException异常)
assertMainThread("observe");
//2.当前绑定的组件(activity或者fragment)状态为DESTROYED的时候, 则会忽视当前的订阅请求
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//3.创建生命周期感知的观察者包装类(把注册进来的observer包装成 一个具有生命周边边界的观察者)
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//4.接着会判断该观察是否已经注册过了,如果是则抛异常,所以要注意,不允许重复注册
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
//5.对应观察者只能与一个owner绑定
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
//6.利用Lifecycle,把观察者被实现了LifeCycleObserver的LifecycleBoundObserver再包装一层,就变成有生命周期变化的观察者了,然后addObserver注册到Lifecycle中,就能监听到宿主生命周期状态的变化
owner.getLifecycle().addObserver(wrapper);
}
总结:
1、observe只能在主线程调用,如果不在主线程注册会抛IllegalStateException异常
2、当前绑定的组件(activity或者fragment)状态为DESTROYED的时候, 则会忽视当前的订阅请求
3、内部会创建生命周期感知的观察者包装类LifecycleBoundObserver(把注册进来的observer包装成 一个具有生命周边边界的观察者)
4、对应观察者只能与一个owner绑定,不允许重复注册
5、最后利用Lifecycle,把观察者注册到LifecycleBoundObserver进去,就能监听到宿主生命周期状态的变化
LifecycleBoundObserver到底承载了哪些信息,接着看...
1.2、LifecycleBoundObserver源码:
从上面的分析可以看出:
利用Lifecycle,把观察者注册到LifecycleBoundObserver进去,这样监听到宿主生命周期状态的变化
一旦一个新的观察者被添加,Lifecycle也会同步它的状态和宿主一致,此时会触发观察者的onStateChanged方法
内部会创建生命周期感知的观察者包装类LifecycleBoundObserver(把注册进来的observer包装成 一个具有生命周边边界的观察者)
它能监听宿主被销毁的事件,从而主动的把自己反注册,避免内存泄漏
此时观察者是否处于活跃状态就等于宿主是否可见, 监听宿主的生命周期,并且宿主不可见时不分发任何数据
LifecycleBoundObserver源码:
//1、LifecycleBoundObserver是LiveData内部类
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() {
//2、观察者是否活跃就等于宿主的状态是否大于等于STARTED;
//如果页面当前不可见,你发送了一条消息,此时是不会被分发的,可以避免后台任务抢占资源,当页面恢复可见才会分发。
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//3、如果当接收到 DESTROYED 的事件会自动解除跟 owner 的绑定
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//否则说明宿主的状态发生了变化,此时会判断宿主是否处于活跃状态
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
//接口,触发观察者的onStateChanged方法
//通过Lifecycle,addObserver(Observer oberver)
//handleLifecycleEvent(Event event)
//宿主(Activity 或 Fragment)每次生命周期变化都会回调onStateChange方法
public interface LifecycleEventObserver extends LifecycleObserver {
/**
* Called when a state transition event happens.
*
* @param source The source of the event
* @param event The event
*/
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
ObserverWrapper 状态变更后,如果观察者处于活跃状态会触发数据的分发流程
//抽象类
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
//ObserverWrapper在每次注册的时候都会重新new,所以mLastVersion每次都是-1开始。
int mLastVersion = START_VERSION;//这里就等于-1
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
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;
//1、如果此时有且只有一个活跃的观察者则触发onActive
if (wasInactive && mActive) {
onActive();
}
//2、没有任何一个活跃的观察者则触发onInactive
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
//3、如果此时观察者处于活跃状态,下面就开始分发数据了
if (mActive) {
dispatchingValue(this);
}
}
}
dispatchingValue(this)数据分发流程控制:(内部执行considerNotify(initiator)方法)
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
//1、如果传递的观察者不为空,则把数据分发给他自己。这个流程是新注册观察者的时候会被触发
considerNotify(initiator);
initiator = null;
} else {
//2、否则遍历集合中所有已注册的的观察者,逐个调用considerNotify,分发数据
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
considerNotify 数据真正分发的地方:
private void considerNotify(ObserverWrapper observer) {
//1、观察者当前状态不活跃就不分发
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.
//2、观察者所在宿主是否处于活跃状态,否则不分发,并且更改观察者的状态为false
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//3、此处判断观察者接收消息的次数是否大于等于 发送消息的次数(observer被创建之初verison=-1 )
if (observer.mLastVersion >= mVersion) {
return;
}
//4、计算最新的发送消息的次数
observer.mLastVersion = mVersion;
//5、这里会执行传入的observer的onChanged方法
observer.mObserver.onChanged((T) mData);
}
2、setValue发送源码分析
2.1 setValue源码分析
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
//这个mVersion是属于LiveData的,然后只在setValue(postValue最终也会调用setValue)的时候会自增1
mVersion++;
mData = value;
dispatchingValue(null);
}
2.2同上observer分析,dispatchingValue(this)数据分发流程控制:(内部执行considerNotify(initiator)方法)
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
//1、如果传递的观察者不为空,则把数据分发给他自己。这个流程是新注册观察者的时候会被触发
considerNotify(initiator);
initiator = null;
} else {
//2、否则遍历集合中所有已注册的的观察者,逐个调用considerNotify,分发数据
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
2.3、considerNotify 数据真正分发的地方:
private void considerNotify(ObserverWrapper observer) {
//1、观察者当前状态不活跃就不分发
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.
//2、观察者所在宿主是否处于活跃状态,否则不分发,并且更改观察者的状态为false
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//3、此处判断观察者接收消息的次数是否大于等于 发送消息的次数(observer被创建之初verison=-1 )
if (observer.mLastVersion >= mVersion) {
return;
}
//4、计算最新的发送消息的次数
observer.mLastVersion = mVersion;
//5、这里会执行传入的observer的onChanged方法
observer.mObserver.onChanged((T) mData);
}
综上分析:LiveData的粘性事件:
这种情况被称为LiveData的粘性事件
通过同一个LiveData
在更改数据的时候调用setValue(postValue最终也会调用setValue)的时候内部维护的mVersion会自增1,mVersion初始值是-1
在监听数据变化的时候,既调用observer监听的时候,每次内部都会在通过包装类中new ObserverWrapper,内部维护了一个mLastVersion变量,mLastVersion也是初始值为-1,所以注意了,每执行一次observer方法内部维护mLastVersion都会新创建而变为-1
结论所以只要之前有发射过一次数据,那么后面注册的观察者都会接收到之前发射过的数据
这也是为什么通常使用LiveData时,在大多数情况下,应用组件的 onCreate() 方法是开始观察 LiveData 对象的正确着手点,就是为了避免粘性事件的发生。