Android LiveData(二):源码分析
有上文对LiveData的基本认识,接下来直接进入LiveData的源码分析,首先进入observer方法,需要注意的是MainActivity继承AppCompatActivity,是LifecycleOwner接口实现类的子孙。而调用observer方法时传入当前MainActivity的上下文,可以理解为owner就是当前的MainActivity。
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//判断当前LifecycleOwner即Activity的生命周期状态,如果为DESTROYED就没必要执行了
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//注释2
//对传入的observer封装为LifecycleBoundObserver,类比Handler机制中将Runnable封装为Message
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//每次注册一个观察者,就会存放到map集合中
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;
}
//注释3
//owner就是LifecycleOwner,而我们MainActivity的父类AppCompatActivity 是LifecycleOwner
//的实现类ComponentActivity的子类,即给我们的MainActivity注册了一个与声明周期相关的观察者
//LifecycleObserver,这样一来就能感知组件的生命周期了。也就是说我们的MainActivity声明周期
//发生变化的时候,会回调wrapper接口,即回调observer接口,也就是触发观察者中的逻辑
owner.getLifecycle().addObserver(wrapper);
}
在注释2处,对观察者observer做了一层封装,集合中保存的是wrapper。注释3处,通过addObserver注册了生命周期的观察监听,到这里我们就大概知道,postValue会触发observer方法,组件即MainActivity生命周期发生变化的时候,也会触发observer方法,具体流程接着往下看。
接下来就从postValue方法发送数据,触发观察者接口回调的流程进行简单分析。进入postValue方法:
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
//注释
//切换到主线程执行
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
也就是说postValue无论在哪个线程执行,都会切换到主线程去执行。意味着它可以在子线程去发送数据,接着往下看,它里面调用了setValue方法,
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方法进行了封装,切换线程,结论就是setValue只能在主线程执行,而postValue即可以在主线程也可以在子线程执行。
接下来进入setValue方法:
protected void setValue(T value) {
assertMainThread("setValue");
//注释1
mVersion++;
mData = value;
//注释2
dispatchingValue(null);
}
setValue方法里面主要关注两处注释处代码即可,注释1处代码后面设计再分析,先进入dispatchingValue方法,
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
//注释1
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
//注释2
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
注意setValue方法中dispatchingValue方法传入参数为null,进入下面注释1处逻辑,如果传入参数不为null,进入注释2处逻辑,遍历所有注册的观察者,执行considerNotify方法:
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
//注释1
observer.activeStateChanged(false);
return;
}
//注释2
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//注释3
observer.mObserver.onChanged((T) mData);
}
mLastVersion和mVersion的初始值均为-1,前面提到过在setValue方法注释1处mVersion++,此时mVersion>mLastVersion, 才会执行注释3处代码,触发接口Observer回调onChanged方法,但是 observer.mLastVersion = mVersion;这一行代码,表示注释3处的代码只会执行一次。
那么问题来了,MainActivity是如何感知生命周期的呢?如何做到先执行postValue方法,后注册观察者依然能触发接口回调的呢?我们目前已知的是前面提到过,在observer方法的注释3处,给owner即MainActivity注册了生命周期的监听接口LifecycleObserver,当生命周期发生改变时,会回调LifecycleBoundObserver的onStateChanged方法,
在该方法中打断点,debug调试,效果如下图:
MainActivity依次调用生命周期方法onCreate()、onStart()、onResume(),会触发ononStateChanged的多次调用,也就是会多次调用activeStateChanged方法。
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
...
//注释1
//该方法返回最近调用的生命周期状态
//例如绑定的MainActivity如果被销毁或处于不可见状态,返回false
//那么activeStateChanged方法中dispatchingValue(this)将不会执行
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
//生命周期发生改变就会回调到这个方法,
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
//如果生命周期DESTROYED,即已经销毁了,就需要将注册的观察者移除
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//注释2
//如果没有被销毁,生命周期发生改变的回调
activeStateChanged(shouldBeActive());
}
...
}
activeStateChanged方法代码如下,只需要重点关注注释1处的dispatchingValue方法,注意是参数不为null哦
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();
}
if (mActive) {
//注释1
dispatchingValue(this);
}
}
再次回到dispatchingValue方法,参数不为null,进入对应的considerNotify方法,还是会根据observer.mLastVersion >= mVersion 来判断是否会继续执行,触发considerNotify方法注释3处的代码,即回调observer的onChanged方法。只有当postValue或setValue执行过了,才会触发,现在就应该清楚了,即使先调用postValue,后注册观察者,生命周期的接口回调会触发Observer接口回调。
considerNotify方法,还是会根据observer.mLastVersion >= mVersion 来判断是否会继续执行,触发considerNotify方法注释3处的代码,只会执行一次,即回调observer的onChanged方法。只有当postValue或setValue执行过了,才会触发,现在就应该清楚了,即使先调用postValue,后注册观察者,生命周期的接口回调会触发Observer接口回调。
上一篇: java递归法求字符串逆序