LiveData 是一种数据持有类,并且可以在给定的生命周期中对数据进行观察。意味着观察者可以和生命周期持有者成对添加。
和其他可被观察的类不同的是,LiveData 是有生命周期感知能力的,这意味着它可以在 activities, fragments, 或者 services 生命周期是活跃状态(STARTED 或 RESUMED)时更新这些组件。
要想使用 LiveData(或者这种有可被观察数据能力的类)就必须配合实现了 LifecycleOwner 的对象使用。在这种情况下,当对应的生命周期对象 DESTORY 时,才能移除观察者。这对 Activity 或者 Fragment 来说显得尤为重要,因为他们可以在生命周期结束的时候立刻解除对数据的订阅,从而避免内存泄漏等问题。
方法的关键逻辑放在了注释中。
/**
* 在 owner 生命周期内添加 observer。事件在主线程上调度。
* 如果 LiveData 已经有了数据,将会被发送到 observer 上。
*
* observer 只会在 owner 状态为 {@link Lifecycle.State#STARTED}
* 或 {@link Lifecycle.State#RESUMED} 的活跃状态时接收事件。
*
* 如果在 owner 到达 {@link Lifecycle.State#DESTROYED} 状态,observer 会自动被移除。
*
* 在 owner 非活跃状态时发生数据变化,它将不会接收任何更新。
* 当它重新回到活跃状态,它将自动获取最后一次有效的数据。
*
* LiveData 在 LifecyclerOwner 未销毁期间会一直强引用着 observer 和 owner。
* 在 LifecyclerOwner 被销毁后会移除对 observer 和 owner 的引用。
*
* 如果 owner 已经处于 {@link Lifecycle.State#DESTROYED} 状态,LiveData 会忽略这次操作。
*
* 如果 wrapper(owner、observer) 在映射已经存在,LiveData 会忽略这次操作。
* 如果 observer 已经绑定了其他的 owner,LiveData 抛出 {@link IllegalArgumentException}。
*/
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// 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;
}
owner.getLifecycle().addObserver(wrapper);
}
ObserverWrapper 是 LiveData 内部的 Observer 包装类,而 LifecycleBoundObserver 继承了它并且实现了 LifecycleEventObserver 接口,使其能监听到生命周期的变化。
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) {
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);
}
}
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
*/
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
/**
* 解绑 observer
*/
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// 立即改变活跃状态,这样就不会分发事件给非活跃 owner
mActive = newActive;
// mActiveCount 是 LiveData 全局变量,用于判断多少个 observer 处于活跃状态。
// wasInactive 用于判断了上次 LiveData 是否处于非活跃状态
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
// 活跃 observer 数量从 0 到 1 时回调
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
// 活跃 observer 数量从 1 到 0 时回调
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
}
有关dispatchingValue(ObserverWrapper)
方法的源码放在 setValue(Object) 分析。
在 observe(LifecycleOwner, Observer)
方法中有一句 ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
,mObservers 是一个 SafeIterableMap 类型的映射,来看看它的部分源码:
public V putIfAbsent(@NonNull K key, @NonNull V v) {
Entry<K, V> entry = get(key);
if (entry != null) {
return entry.mValue;
}
put(key, v);
return null;
}
protected Entry<K, V> put(@NonNull K key, @NonNull V v) {
Entry<K, V> newEntry = new Entry<>(key, v);
mSize++;
if (mEnd == null) {
mStart = newEntry;
mEnd = mStart;
return newEntry;
}
mEnd.mNext = newEntry;
newEntry.mPrevious = mEnd;
mEnd = newEntry;
return newEntry;
}
可以看到内部是一个非线程安全的链表存储键值对,putIfAbsent(K, V)
通过 key 去查找映射内是否有对应的 value,如果存在则直接返回,不存在就放入新的数据并返回空。
/**
* 和 {@link LiveData#observe(LifecycleOwner, Observer)} 类似,
* 但是一直保持 active,意味着它会接收所有事件并且不会被自动移除。
* 可以手动调用 {@link #removeObserver(Observer)} 来停止对 LiveData 的监听。
* 当 LiveData 有这种 observer,将被视为 active。
*
* 当 observer 已经和 owner 绑定,LiveData 会抛出 {@link IllegalArgumentException} 异常。
*/
@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);
}
/**
* 设置值。如果有活跃的 observer 则将值分发给它们。
*
* 该方法必须在主线程执行。如果需要后台执行,使用 {@link #postValue(Object)}
*/
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
mVersion
变量初始值为 -1,每次 setValue(Object)
都会自增 1,相当于记录最新数据的版本。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// mDispatchingValue 是为了解决并发调用 dispatchingValue 的情况
if (mDispatchingValue) {
// mDispatchInvalidated == true 时会让下面的 while 循环再执行一次
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;
}
该方法出现在两个地方,一个是 LifecycleOwner 生命周期发生变化时,另一个是 setValue(Object) 时。
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// 在分发之前检查最后的状态。因为有可能状态已经改变但我们还没有接收到事件。
//
// 我们仍然先检查 observer.active 来让它作为一个事件的入口。
// 所以即使 observer 变为活跃状态,如果我们还没有接收到事件,
// 我们最好不要去通知,以便保持一个可预测的通知顺序。
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
observer 的 mLastVersion
初始值也为 -1,用于判断当前监听的数据是 LiveData 数据的哪个版本,当 mLastVersion
小于 mVersion
说明当前监听的数据不是最新,才会去回调 onChanged(Object)
。
从上面的源码可以看出注册 observer 后有两种情况:
observe(LifecycleOwner, Observer)
方法中 owner 注册了 observeronStateChanged(LifecycleOwner, Lifecycle.Event)
observer.activeStateChanged(boolean)
dispatchingValue(ObserverWrapper)
,这里只传当前 observerconsiderNotify(ObserverWrapper)
,内部调用了 observer.onChanged(Object)
setValue(Object)
、postValue(Object)
):
observe(LifecycleOwner, Observer)
方法中 mObservers 映射添加了 observersetValue(Object)
时调用了 dispatchingValue(null)
considerNotify(ObserverWrapper)
,内部调用了 observer.onChanged(Object)