Android jetpack LiveData(二)原理篇
-
- 引言
- 源码前置分析
-
- 核心类
- 源码
-
- 第一步,定义LiveData对象
- 第二步,观察LiveData数据
- [第三步: 设置LiveData数据](#第三步: 设置LiveData数据)
- 到这里我们先总结下黏性数据的步骤:
- 小结
引言
上一篇我们学习了LifeCycle的简单使用Android jetpack LiveData(一)使用篇,那在这一篇主要学习LiveData的原理。

源码前置分析
核心类
LiveData:抽象类,定义了 LiveData 的基本行为和接口。
MutableLiveData:LiveData 的子类,提供了 setValue 和 postValue 方法用于更新数据。
Observer:观察者接口,用于定义数据更新时的回调方法。
LifecycleBoundObserver:实现了 Observer 接口,并且具有生命周期感知能力,确保只在合适的生命周期状态下通知观察者。
LiveData.java
定义了基本的数据观察和设置方法。
kotlin
public abstract class LiveData<T> {
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
...
}
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
...
}
protected void postValue(T value) {
...
}
@MainThread
protected void setValue(T value) {
...
}
protected void onActive() {
}
protected void onInactive() {
}
}
MutableLiveData.java
LiveData的子类,
kotlin
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
源码
我们按照使用的顺序来进行源码分析
第一步,定义LiveData对象

kotlin
public MutableLiveData() {
super();
}
在核心类里面了解到MutableLiveData是LiveData的子类,所以我们去LiveData中看定义。在这里进行数据对象初始化。
kotlin
public abstract class LiveData<T> {
public LiveData(T value) {
mData = value;
mVersion = START_VERSION + 1;
}
public LiveData() { // 逻辑走这里
mData = NOT_SET;
mVersion = START_VERSION; // -1 (初始为-1 哦,后面会用到)
}
}
第二步,观察LiveData数据

这个observe方法同样进入LiveData.java类中分析。
kotlin
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 1
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// 2
return;
}
// 3
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;
}
// 4
owner.getLifecycle().addObserver(wrapper);
}
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
这里我贴出了两个观察方法。
observe方法不需要自己手动清理观察者,当LifecycleOwner进入DESTROYED状态时,会自动移除观察者。
下面这个observeForever会一直观察,不需要传入lifecycleOwner,但是需要自己在不用时销毁removeObserver。
// 1 :第一步要验证这个方法是否在主线程,证明该方法必须要在主线程调用。否则会抛出异常崩溃;
// 2 :第二步是判断当LifecycleOwner进入DESTROYED状态时,自动移除观察者。这个owner就是我们调用该方法时传入的owner;
// 3 :第三步出现了新的观察类LifecycleBoundObserver ,可以看到它实现了LifecycleEventObserver ,这个在我们学习Lifecycle的时候有讲过,主要是通过onStateChanged来观察生命周期,可以看下面的代码。
// 4 :核心。owner.getLifecycle().addObserver(wrapper);兜兜转转又回到了Lifecycle里面,把这个观察者添加到lifecycle里面。之前在Lifycycle原理篇有讲过,为lifycycle添加观察者,等lifecycleowner的生命周期变化,就会出发lifecycle event事件。
kotlin
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() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
接着往下看这个代码activeStateChanged(shouldBeActive());能看到当前状态是active的时候,会分发数据dispatchingValue(this);
kotlin
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
dispatchingValue在LiveData中,这个方法用于将最新的值分发给观察者。
kotlin
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 首先检查是否正在分发值(mDispatchingValue为true)。
// 如果是,则设置mDispatchInvalidated = true并立即返回。
// 这意味着如果有递归调用,它会标记当前分发无效,让外层循环知道需要重新执行。
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
//循环结束后,检查mDispatchInvalidated标志。
// 如果为true,表示在分发过程中发生了无效化
//(通常是因为有新的数据变化导致需要重新分发),那么循环会再次执行,
//重新开始分发。否则退出循环。
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false; // 分发结束
}
上述核心方法:considerNotify(initiator);
considerNotify 是 LiveData 中实际触发观察者回调的关键方法,它在 dispatchingValue 中被调用,用于向单个观察者派发数据 。 observer.mObserver.onChanged((T) mData);确保只有在观察者处于正确状态且数据确实更新时才通知,同时维持了与 Lifecycle 组件的生命周期安全集成。
kotlin
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) { // 这块是来判断黏性数据的
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
这里最后就是我们回调的onChanged方法

那我们通过上面的分析就知道,livedata通过注册lifecycle观察者,在事件变更时能接收到变化。接下来我们继续看第三步;
第三步: 设置LiveData数据
使用setValue(主线程)/postValue(子线程)的形式去设置Livedata数据

因为postValue最终也会调用到setValue,所以我们从postValue()看起
kotlin
protected void postValue(T value) {
boolean postTask;
// 加同步锁考虑线程安全
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
// 在这里线程切换到主线程!!!
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
看上述代码,看到在postValue()中将线程切换到主线程中,在主线程中又调用了setValue()。至此,我们就知道postValue最终也会通过runnable调用到setValue().
kotlin
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++; // 首次-1 -> 0
mData = value;
dispatchingValue(null); // null,进入for循环加到观察者里
}
可以看到上面的setValue是必须要在主线程中调用的。如果在子线程调用会抛出异常。接着往下看。mVersion++,此时首次进入这个值从-1变成了0,同时传入wrapper是null(这个方法我们再第二步中也有描述)
kotlin
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
首次:
mObservers可以有多个,是一个map集合。因此进入for循环全部加进来。
此时我们再去看considerNotify方法中的version
// mLastVersion 为-1
// mVersion为0,没法进入这里,往下走
后续 :
走传入的observer不为空的逻辑,直接调用。
kotlin
if (initiator != null) {
considerNotify(initiator);
initiator = null;
}
kotlin
int mLastVersion = START_VERSION; // -1
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 不触发
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
// 直接把数据分发下去。这个数据在这里是指代的订阅之前接设置好的黏性数据哦!!!后续就是订阅之后传入的数据了。
observer.mObserver.onChanged((T) mData);
}
到这里我们先总结下黏性数据的步骤:
1、在订阅之前先设置好value, liveData.value = 20

2、mVersion++ 变为0
3、将设置的value传入mData,mData = value; 也就是 mData = 20,埋下伏笔
4、接着我们订阅观察者。

在LifecycleBoundObserver中,当我们的owener启动(生命周期变化)后,会通过activeStateChange分发当前数据!(见下图),这里就不走循环了,不需要再把observer加到map集合了。


5、后面就是considerNotify判断observer.mLastVersion >= mVersion.这里mLastVersion为-1,mVersion在2中变成了0,因此无法进入判断。mLastVersion设置为0,同时触发我们观察者的onChanged((T) mData)。这里的mData就是什么!!没错,就是那个在1中设置好的数据20!
小结
可以用这张图来表示。

下一步可能会讲讲怎么解决数据倒灌(黏性数据)。
ing...