LiveData
LiveData
是一個可以感知LifecycleOwner
生命週期的可被觀察的數據容器。
接下來,我們從 3 個角度來分析 LiveData
。
- 數據容器;
- 可被觀察;
- 感知生命週期
數據容器
LiveData
它實際上是一個數據容器,我們設置的數據真正是存放在 mData 裏面的。
static final int START_VERSION = -1;
private static final Object NOT_SET = new Object();
private volatile Object mData = NOT_SET;
public T getValue() {
Object data = mData;
if (data != NOT_SET) {
return (T) data;
}
return null;
}
protected void setValue(T value) {
mVersion++;
mData = value;
dispatchingValue(null);
}
可被觀察
LiveData
它是可以被觀察的數據源。
一個數據可以被觀察,那麼它內部肯定有一個集合去存放觀察者,同時會暴露註冊和移除觀察者的方法。
private SafeIterableMap<Observer<T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
// ...
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
// 同一個LifecycleObserver 只能 綁定一個 LifecycleOwner
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
// ...
}
@MainThread
public void removeObserver(@NonNull final Observer<T> observer) {
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
return;
}
// ...
}
@MainThread
public void removeObservers(@NonNull final LifecycleOwner owner) {
for (Map.Entry<Observer<T>, ObserverWrapper> entry : mObservers) {
if (entry.getValue().isAttachedTo(owner)) {
removeObserver(entry.getKey());
}
}
}
感知生命週期
LiveData
是可以感知LifecycleOwner
的生命週期的。
那其實就是內部給 LifecycleOwner
註冊了一個 LifecyclObserver
。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
// 如果生命週期不是活躍的,則不進行觀察者的註冊
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
// 這裏將 LifecycleOwner 和 Observer 一一對應,保證在不活躍的時候能自動移除掉
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// ...
owner.getLifecycle().addObserver(wrapper);
}
然後,在移除 Observer
的時候, 需要將對應的 LifecycleObserver
從 LifecycleOwner
裏面移除掉 。
@MainThread
public void removeObserver(@NonNull final Observer<T> observer) {
ObserverWrapper removed = mObservers.remove(observer);
// ...
removed.detachObserver();
removed.activeStateChanged(false);
}
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
super(observer);
mOwner = owner;
}
// 這裏就是在 removeObserver 的時候調用的,移除和 LifecycleOwner 的關係。
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
好像還是沒有看出 LiveData
感知生命週期做了些什麼事情。
不要方,我們來看下 LifecycleBoundObserver
,它實現了 GenericLifecycleObserver
接口。
public interface GenericLifecycleObserver extends LifecycleObserver {
// 當 LifecycleOwner 生命週期變化的時候會回調這個方法
void onStateChanged(LifecycleOwner source, Lifecycle.Event event);
}
每當 LifecycleOwner
的生命週期發生變化的時候,都會回調 onStateChanged()
方法。 我們來看下 LifecycleBoundObserver
對這個方法的實現。
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
// 當生命週期被銷燬的時候自動移除 `Observer`
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
細緻的你一定發現了,在 removeObserver()
和 onStateChanged()
都調用了 activeStateChanged()
,它是 ObserverWrapper
的一個方法。
private abstract class ObserverWrapper {
final Observer<T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
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) {
dispatchingValue(this);
}
}
}
可以看到,當 Observer
對應的 LifecycleOwner
由不活躍變成活躍狀態的時候, LiveData
會主動去通知 Observer
刷新一次。
接下來,我們再來看看 dispatchingValue()
。
private void dispatchingValue(@Nullable ObserverWrapper initiator) {
// ...
// 生命週期從不活躍變爲活躍的時候,通知指定的Observer
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
// 會通知所有的 Observer
for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
// 主要是這個方法在做數據刷新
considerNotify(iterator.next().getValue());
}
}
// ...
}
我們再來看看 considerNotify()
private void considerNotify(ObserverWrapper observer) {
// 如果 Observer 對應的 LifecycleOwner 是不活躍的,則不進行通知。
if (!observer.mActive) {
return;
}
// 不活躍的時候會將 Wrapper 置爲不活躍狀態
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 說明 Observer 已經是最新的值了
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
// 通知 Observer 刷新
observer.mObserver.onChanged((T) mData);
}