LiveData源码解析
源码版本:2.4.0
需会使用:Lifecycle
导航:
使用
监听值
liveData.observe(LifecycleOwner, Observer)
liveData.observeForever(Observer)
设置值
liveData.setValue(value)
liveData.postValue(value)
移除监听
liveData.removeObserver(Observer)
liveData.removeObservers(LifecycleOwner)
源码
构造函数
// 有默认值
public LiveData(T value) {
mData = value;
// 版本号加1,以标记此LivaData的数据版本要比观察者包装者的数据版本要高(新),以进行通知观察者Observer。
mVersion = START_VERSION + 1;
}
// 无默认值
public LiveData() {
mData = NOT_SET;
// 版本号和观察者包装者的版本相同,以不进行通知观察者Observer。
mVersion = START_VERSION;
}
监听值
observe
LiveData --> observe方法
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 断言只能在主线程调用,否则抛异常。
assertMainThread("observe");
// 当Lifecycle处于DESTROYED状态时,再观察是没有意义的,直接返回。
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// 创建新的Observer包装者LifecycleBoundObserver,让其监听生周周期变化,并处理。
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// mObservers是一个Map,key为Observer,value为ObserverWrapper,持有多个观察者包装者。
// putIfAbsent,如果传入key对应的value已经存在,就返回存在的value,不进行替换。如果不存在,就添加key和value,并返回null。
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
// 该Observer对象已经被该LiveData持有,且该值ObserverWrapper对象没依附于当前的Lifecycle对象,说明该值ObserverWrapper之前已经被其它的Lifecycle对象添加,再被当前的Lifecycle添加,则直接抛出异常。
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
// 该Observer对象已经被该LiveData持有,且该值ObserverWrapper对象依附于当前的Lifecycle对象,说明该值ObserverWrapper之前已经被当前的Lifecycle对象添加,则直接返回。
return;
}
// 使用Lifecycle控件,观察该ObserverWrapper对象生命周期。
owner.getLifecycle().addObserver(wrapper);
}
说明:
- 必须在主线程调用
observe
方法。- 同一个
LiveData
,同一个Observer
,observe
方法不能用不同的Lifecycle
。
observe
方法就是把我们的Observer
对象包装成LifecycleBoundObserver
后存入mObservers
中,并将其添加到Lifecycle
中,以监听生命周期变化。它继承ObserverWrapper
并实现了LifecycleEventObserver
。
ObserverWrapper类
private abstract class ObserverWrapper {
// 传入的观察者对象
final Observer<? super T> mObserver;
// 此观察者包装者,是否处于活跃状态,只有活跃状态的时候才可以被通知。
boolean mActive;
// 此观察者包装者,数据的版本。
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
// 此观察者包装者,是否应该处于活跃状态。
abstract boolean shouldBeActive();
// 此观察者包装者,是否依附到LifecycleOwner的Lifecycle组件中。
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
// 此观察者包装者,分离Observer,即不再观察此ObserverWrapper。
void detachObserver() {
}
// 此观察者包装者,活跃状态改变。
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
// 新状态和现有状态相同,则不处理。
return;
}
// 记录活跃状态
mActive = newActive;
// 改变活跃观察者的数量,此观察者包装者,变活跃+1,变非活跃-1。
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
// 活跃状态下,进行分发值。
dispatchingValue(this);
}
}
}
然后我们再看被Lifecycle
添加的,生命周期可感知的LifecycleBoundObserver
类。
LifecycleBoundObserver类
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
// 传入的Lifecycle持有者对象
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
// 此观察者包装者,是否应该处于活跃状态。
@Override
boolean shouldBeActive() {
// onStart,onResume,onPause这三个状态处于活跃状态,其它处于非活跃状态。
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
// LifecycleEventObserver接口实现方法,生命周期状态改变的时候调用。
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
// 当生命周期状态为destroyed的时候,把该观察者移除。
// 然后在removeObserver内部,会调用detachObserver方法,将此ObserverWrapper从Lifecycle中移除。并调用activeStateChanged方法,通知活跃状态改为:非活跃的。
removeObserver(mObserver);
return;
}
// 生命周期状态改变,通知活跃状态改变。
// 加While循环的目的,防止执行activeStateChanged的时候,mOwner的生命周期的状态更改。
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
// 通知活跃状态改变
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
// 此观察者包装者,是否依附到LifecycleOwner的Lifecycle组件中。
@Override
boolean isAttachedTo(LifecycleOwner owner) {
// 如果持有的(传入的)mOwner与要比较的owner相同,则认为此观察者包装者,是依附到传入的Lifecycle组件中。
return mOwner == owner;
}
// 此观察者包装者,分离Observer,即不再观察此ObserverWrapper。
@Override
void detachObserver() {
// Lifecycle移除此ObserverWrapper
mOwner.getLifecycle().removeObserver(this);
}
}
LiveData --> removeObserver方法
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
// 断言只能在主线程调用,否则抛异常。
assertMainThread("removeObserver");
// 将observer从mObservers中移除
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
// removed为空,则代表observer就没有被mObservers添加,直接返回。
return;
}
// 被移除的观察者包装者,不再观察ObserverWrapper。
removed.detachObserver();
// 被移除的观察者包装者,通知活跃状态改为:非活跃的。
removed.activeStateChanged(false);
}
代码流程:
observe
方法将LifecycleBoundObserver
添加到mObservers
,并添加到Lifecycle
观察。- 当生命周期状态改变的时候,通知
LifecycleBoundObserver
的onStateChanged
方法。- 当生命周期状态改变为
destroyed
的时候,会调用detachObserver
方法,将此ObserverWrapper
从Lifecycle
中移除。并调用activeStateChanged
方法,通知活跃状态为:非活跃的。- 当生命周期状态改变为其它的时候,会调用
activeStateChanged
方法,通知活跃状态为:onStart
,onResume
,onPause
为活跃的,其它为非活跃的。activeStateChanged
方法,会过滤相同的状态。并调用changeActiveCounter
方法,改变活跃观察者的数量,以及如果是活跃状态,则调用dispatchingValue
方法,进行分发值。
说明:
LiveData.observe(LifecycleOwner, Observer)
,传入的Observer
,不需要手动移除,它会在生命周期状态为DESTROYED
的时候,自动移除。onStart
,onResume
,onPause
为活跃状态,其它为非活跃状态。非活跃状态下,不进行分发值。- 非活跃状态下,设置的值,直到生命周期状态改变为活跃状态,就会将值进行分发,所以
LiveData
自带粘性事件特征。
接下来,我们来看一个changeActiveCounter
方法,改变活跃观察者的数量。
LiveData --> changeActiveCounter方法
@MainThread
void changeActiveCounter(int change) {
// 记录之前活跃的数量
int previousActiveCount = mActiveCount;
// 记录现在的活跃的数量,change:活跃状态为+1,非活跃状态为-1。
mActiveCount += change;
if (mChangingActiveState) {
// 如果是改变中,则返回。
return;
}
// 标记为改变中
mChangingActiveState = true;
try {
// 之前的活跃数量和现在的活跃数量不一致,那么将执行下面的通知变活跃/变非活跃逻辑。
// 加while的原因,因为当执行下面判断逻辑的时候,changeActiveCounter方法再次调用,导致mActiveCount值更改,所以加while使其保持一致。
while (previousActiveCount != mActiveCount) {
// 之前的活跃数量为0,并且现在的活跃数量大于0,即说明之前是非活跃状态,然后现在是活跃状态,则需要调用变活跃方法。
boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0;
// 之前的活跃数量是大于0,并且现在的活跃数量为0,即说明之前是活跃状态,然后现在是非活跃状态,则需要调用变非活跃方法。
boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0;
// 让previousActiveCount和mActiveCount保持一致
previousActiveCount = mActiveCount;
if (needToCallActive) {
// 需要调用变活跃方法,它是空方法,可以自定义LiveData实现。
onActive();
} else if (needToCallInactive) {
// 需要调用变非活跃方法,它是空方法,可以自定义LiveData实现。
onInactive();
}
}
} finally {
// 标记为改变结束
mChangingActiveState = false;
}
}
LiveData --> dispatchingValue方法
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
// 分发值中,则标记分发失效的。
mDispatchInvalidated = true;
return;
}
// 标记分发值中
mDispatchingValue = true;
do {
// 清空分发失效的标记
mDispatchInvalidated = false;
if (initiator != null) {
// initiator不为空,为活跃状态变化传入的ObserverWrapper,则直接通知该ObserverWrapper。
// 考虑通知
considerNotify(initiator);
// 直接清空标记
initiator = null;
} else {
// initiator为空,为setValue()调用,则通知所有的ObserverWrapper。
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
// 考虑通知
considerNotify(iterator.next().getValue());
// 在遍历过程中,如果遇到值更新(dispatchingValue调用),则立即退出当前分发,
// 则继续走while,再执行 do 中逻辑。
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
// 标记分发值结束
mDispatchingValue = false;
}
LiveData --> considerNotify方法
@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
// 非活跃状态,则不进行后续处理。
return;
}
if (!observer.shouldBeActive()) {
// mActive为活跃状态,shouldBeActive()为非活跃状态,则以shouldBeActive()状态为主,同步状态,不进行后续处理。
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
// observer数据的版本[大于等于]当前LiveData数据的版本,则说明数据已经同步,则不进行后续处理。
return;
}
// 观察者包装者,更新版本。
observer.mLastVersion = mVersion;
// 观察者包装者,通知传入的观察者,数据改变。
observer.mObserver.onChanged((T) mData);
}
代码流程:
activeStateChanged
方法,调用changeActiveCounter
方法更改活跃观察者的数量,并通知LiveData
变活跃/变非活跃。activeStateChanged
方法,如果是活跃状态,则调用dispatchingValue
方法,进行分发值。dispatchingValue
方法,如果是活跃状态改变而分发值,则直接让此ObserverWrapper考虑通知(调用considerNotify
方法)。如果是setValue
()而分发值,则让所有的ObserverWrapper考虑通知。considerNotify
方法,会进行最终的判断,如果是活跃的,并且ObserverWrapper
的数据版本过老,则进行通知。
observeForever
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
// 断言只能在主线程调用,否则抛异常。
assertMainThread("observeForever");
// 创建新的Observer包装者AlwaysActiveObserver,让其处理。
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
// 该Observer对象已经被该LiveData持有,且该ObserverWrapper是LifecycleBoundObserver对象,说明该Observer已经被Lifecycle观察,再被Forever观察,则直接抛出异常。
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
// 该Observer对象已经被该LiveData持有,且该ObserverWrapper是非LifecycleBoundObserver对象,说明该Observer已经被Forever观察,再被Forever观察,则直接返回。
return;
}
// 立即通知活跃状态为:活跃的。
wrapper.activeStateChanged(true);
}
说明:
- 必须在主线程调用
observeForever
方法。- 同一个
LiveData
,同一个Observer
,observe
方法、observeForever
方法不能用同一个Observer
。
observeForever
方法就是把我们的Observer
对象包装成AlwaysActiveObserver
后存入mObservers
中,并立即通知活跃状态为:活跃的。
LifecycleBoundObserver类
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
// 此观察者包装者,是否应该处于活跃状态。
@Override
boolean shouldBeActive() {
// 始终处于活跃状态,此方法只在shouldBeActive方法内调用。
return true;
}
}
代码流程:
observeForever
方法,将观察者包装者AlwaysActiveObserver
添加到mObservers
,并立即调用activeStateChanged
方法,通知活跃状态为:活跃的。activeStateChanged
方法,活跃状态下,会调用dispatchingValue
方法,进行分发值。dispatchingValue
方法,则直接让此ObserverWrapper考虑通知(调用considerNotify
方法)。considerNotify
方法,会进行最终的判断,如果是活跃的,并且ObserverWrapper
的数据版本过老,则进行通知。
说明:
LiveData.observeForever(Observer)
,传入的Observer
,需要手动移除。
设置值
setValue
@MainThread
protected void setValue(T value) {
// 断言只能在主线程调用,否则抛异常。
assertMainThread("setValue");
// 当前LiveData数据的版本,每次有新值版本都会+1,用于和观察者包装者的版本进行比较,如果观察者包装者的版本小于此值,则进行通知更新。
mVersion++;
// 记录需要分发的值
mData = value;
// 进行分发值,传null代表考虑分发给所有的观察者包装者。
dispatchingValue(null);
}
postValue
protected void postValue(T value) {
// 是否要发送任务
boolean postTask;
// 加synchronized,防止并发,保证线程安全。
synchronized (mDataLock) {
// 是否要发送,如果mPendingData != NOT_SET,即上一次的post没有执行完,再发送新值,则不再发送。
postTask = mPendingData == NOT_SET;
// 记录要待处理的数据
mPendingData = value;
}
if (!postTask) {
// 不发送,直接返回。
return;
}
// 使用Handler,post到主线程,设置值。
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
// 记录新值,防止mPendingData更改
Object newValue;
// 加synchronized,防止并发,保证线程安全。
synchronized (mDataLock) {
// 记录新值
newValue = mPendingData;
// mPendingData重置,标记执行完成。
mPendingData = NOT_SET;
}
// 调用setValue,设置新值。
setValue((T) newValue);
}
};
代码流程:
setValue
方法,会调用dispatchingValue
方法,进行分发值。dispatchingValue
方法,让全部ObserverWrapper考虑通知(调用considerNotify
方法)。considerNotify
方法,会进行最终的判断,如果是活跃的,并且ObserverWrapper
的数据版本过老,则进行通知。
说明:
postValue
方法,也是调用的setValue
方法。
移除监听
removeObserver
移除单个Observer
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
// 断言只能在主线程调用,否则抛异常。
assertMainThread("removeObserver");
// 将observer从mObservers中移除
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
// removed为空,则代表observer就没有被mObservers添加,直接返回。
return;
}
// 被移除的观察者包装者,不再观察ObserverWrapper。
removed.detachObserver();
// 被移除的观察者包装者,通知活跃状态改为:非活跃的。
removed.activeStateChanged(false);
}
removeObservers
移除LifecycleOwner所属的所有Observer
@SuppressWarnings("WeakerAccess")
@MainThread
public void removeObservers(@NonNull final LifecycleOwner owner) {
// 断言只能在主线程调用,否则抛异常。
assertMainThread("removeObservers");
for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
if (entry.getValue().isAttachedTo(owner)) {
// 只有所属于LifecycleOwner的才会移除,如observeForever添加的不会移除。
removeObserver(entry.getKey());
}
}
}
总结
以上就是全面的Jetpack-LiveData
源码了!之后会出Jetpack
其它源码系列,请及时关注。如果你有什么问题,大家评论区见!
最后推荐一下我的网站,开发者的技术博客: devbolg.cn ,目前包含android相关的技术,之后会面向全部开发者,欢迎大家来体验!