1. Livedata特性
LiveData 是一種可觀察的數據存儲器類。並且具有生命週期感知能力,能遵循其他應用組件(如 Activity、Fragment 或 Service)的生命週期。
1.1 只有當它關聯的應用組件處於生命週期活躍狀態時,纔會通知對應觀察者。
1.2 當關聯的應用組件的狀態變爲 DESTROYED 時,便可移除此觀察者,避免內存泄露。
1.3 LiveData 僅在數據發生更改時才發送更新,並且僅發送給活躍觀察者。此行爲的一種例外情況是,觀察者從非活躍狀態更改爲活躍狀態時也會收到更新。此外,如果觀察者第二次從非活躍狀態更改爲活躍狀態,則只有在自上次變爲活躍狀態以來,值發生了更改時,它纔會收到更新。
2. 原理介紹
2.1 Livedata.observe方法
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//如當前LifecycleOwner的狀態的是DESTROYED,就不綁定
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//創建一個LifecycleBoundObserver(生命週期限制的觀察者)
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//將觀察者添加到mObservers map
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
//如果已經存在並且觀察者對應的LifecycleOwner不是之前綁定的LifecycleOwner報錯
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
//如果存在直接返回
if (existing != null) {
return;
}
//將觀察者生命週期和LifecycleOwner對應的Lifecycle綁定
//當LifecycleOwner的生命週期發生變化時,回調LifecycleBoundObserver中的 onStateChanged
owner.getLifecycle().addObserver(wrapper);
}
1,observe方法先判斷LifecycleOwner是否已經處於DESTROYED的狀態,如果是就不綁定;
2,然後將創建一個LifecycleBoundObserver,並且將observer和LifecycleBoundObserver添加到觀察者map中;
3,最後將LifecycleBoundObserver和LifecycleOwner的生命週期綁定。
2.2 LifecycleBoundObserver
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);
}
// 當LifecycleOwner生命週期發生變化時,調用這個函數
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
// 當LifecycleOwner的生命週期爲DESTROYED,移除觀察者
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
//LifecycleOwner生命週期改變時,如果LifecycleOwner生命週期處於活躍狀態,更新數據
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
2.3 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();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
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);
}
}
}
2.4 Livedata.dispatchingValue
void dispatchingValue(@Nullable ObserverWrapper initiator) {
//如果正在刷新數據,mDispatchInvalidated置爲true,表示之前的刷新無效
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
//如果ObserverWrapper不爲null,則只刷新傳入的ObserverWrapper
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;
}
1,如果傳入觀察者,則只刷新當前觀察者,用於LifecycleOwner生命週期改變時,因爲所有的觀察者都綁定了LifecycleOwner的生命週期,所以這裏還是刷新所有觀察者;
2,如果沒有傳入觀察者,遍歷觀察者map,刷新所有觀察者;
3,如果刷新的時候,此方法被再次調用,會放棄當前刷新,重新再開始下一輪刷新。
2.5 Livedata.considerNotify
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
/ 如果當前LifecycleOwner的生命週期是非活躍,不回調onChanged
//並在LifecycleBoundObserver 中記錄狀態,當生命週期變爲活躍,去更新數據
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//調用觀察者的onChanged
observer.mObserver.onChanged((T) mData);
}
2.5 Livedata.setValue
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
setValue也是調用了dispatchingValue方法,傳的參數時null,更新所有觀察者。