1. Livedata特性
LiveData 是一種可觀察的數(shù)據(jù)存儲器類。并且具有生命周期感知能力,能遵循其他應(yīng)用組件(如 Activity、Fragment 或 Service)的生命周期。
1.1 只有當(dāng)它關(guān)聯(lián)的應(yīng)用組件處于生命周期活躍狀態(tài)時,才會通知對應(yīng)觀察者。
1.2 當(dāng)關(guān)聯(lián)的應(yīng)用組件的狀態(tài)變?yōu)?DESTROYED 時,便可移除此觀察者,避免內(nèi)存泄露。
1.3 LiveData 僅在數(shù)據(jù)發(fā)生更改時才發(fā)送更新,并且僅發(fā)送給活躍觀察者。此行為的一種例外情況是,觀察者從非活躍狀態(tài)更改為活躍狀態(tài)時也會收到更新。此外,如果觀察者第二次從非活躍狀態(tài)更改為活躍狀態(tài),則只有在自上次變?yōu)榛钴S狀態(tài)以來,值發(fā)生了更改時,它才會收到更新。
2. 原理介紹
2.1 Livedata.observe方法
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//如當(dāng)前LifecycleOwner的狀態(tài)的是DESTROYED,就不綁定
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//創(chuàng)建一個LifecycleBoundObserver(生命周期限制的觀察者)
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//將觀察者添加到mObservers map
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
//如果已經(jīng)存在并且觀察者對應(yīng)的LifecycleOwner不是之前綁定的LifecycleOwner報錯
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
//如果存在直接返回
if (existing != null) {
return;
}
//將觀察者生命周期和LifecycleOwner對應(yīng)的Lifecycle綁定
//當(dāng)LifecycleOwner的生命周期發(fā)生變化時,回調(diào)LifecycleBoundObserver中的 onStateChanged
owner.getLifecycle().addObserver(wrapper);
}
1,observe方法先判斷LifecycleOwner是否已經(jīng)處于DESTROYED的狀態(tài),如果是就不綁定;
2,然后將創(chuàng)建一個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);
}
// 當(dāng)LifecycleOwner生命周期發(fā)生變化時,調(diào)用這個函數(shù)
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//LifecycleOwner生命周期改變時,如果LifecycleOwner生命周期處于活躍狀態(tài),更新數(shù)據(jù)
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
1,當(dāng)LifecycleOwner的生命周期變化是會調(diào)用LifecycleBoundObserver的onStateChanged方法;
2,判斷LifecycleOwner如果處于DESTROYED,移除觀察者;
3,否則如果當(dāng)前是活躍狀態(tài),就將最新值通知給所有觀察者。
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) {
//判斷和上次生命周期是否發(fā)生變化,沒變化直接返回
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
//有變化,且是活躍狀態(tài),更新數(shù)據(jù)
if (mActive) {
dispatchingValue(this);
}
}
}
2.4 Livedata.dispatchingValue
void dispatchingValue(@Nullable ObserverWrapper initiator) {
//如果正在刷新數(shù)據(jù),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());
//刷新數(shù)據(jù)的時候,如果在次調(diào)用此方法,則重新刷新
if (mDispatchInvalidated) {
break;
}
}
}
//刷新數(shù)據(jù)的時候,如果在次調(diào)用此方法,則重新刷新
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
1,如果傳入觀察者,則只刷新當(dāng)前觀察者,用于LifecycleOwner生命周期改變時,因為所有的觀察者都綁定了LifecycleOwner的生命周期,所以這里還是刷新所有觀察者;
2,如果沒有傳入觀察者,遍歷觀察者map,刷新所有觀察者,用于Livedata持有數(shù)據(jù)改變時;
3,如果刷新的時候,此方法被再次調(diào)用,會放棄當(dāng)前刷新,重新再開始下一輪刷新。
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.
/ 如果當(dāng)前LifecycleOwner的生命周期是非活躍,不回調(diào)onChanged
//并在LifecycleBoundObserver 中記錄狀態(tài),當(dāng)生命周期變?yōu)榛钴S,去更新數(shù)據(jù)
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//調(diào)用觀察者的onChanged
observer.mObserver.onChanged((T) mData);
}
2.5 Livedata.setValue
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
setValue也是調(diào)用了dispatchingValue方法,傳的參數(shù)時null,更新所有觀察者。
總結(jié):
Livedata通知觀察者分為兩種情況
1,LifecycleOwner生命周期從非活躍變成活躍狀態(tài)時:
Livedata添加一個觀察者時,會關(guān)聯(lián)一個LifecycleOwner,然后把這個觀察者包裝成一個LifecycleBoundObserver,和LifecycleOwner的Lifecycle關(guān)聯(lián),當(dāng)LifecycleOwner的生命周期變化時,會調(diào)用LifecycleBoundObserver的onStateChanged方法,在這個方法中判斷當(dāng)前生命周期和上次的生命周期是否是同一類型(要么活躍要么非活躍),如果是,就直接返回,避免重復(fù)通知(start通知了,resume就不需要通知了),如果不是同一類型,并且當(dāng)前生命周期是活躍狀態(tài),就調(diào)用dispatchingValue方法通知觀察者,判斷LifecycleOwner是否時活躍狀態(tài),如果是,將Livedata中持有的最新更新給觀察者。
2,Livedata中的值改變時:
同樣是調(diào)用dispatchingValue,判斷LifecycleOwner是否時活躍狀態(tài),如果是,就遍歷通知所有觀察者。
3,livedata粘性事件:第一次添加觀察者會收到數(shù)據(jù),原因是,LifecycleOwner向觀察者刷新生命周期事件,解決方法:自定義一個類實現(xiàn)livedata,定義一個atomicboolean變量,初始值為false,setvalue設(shè)置為true,在這個類發(fā)消息給觀察者前,將這個變量從ture轉(zhuǎn)成false。

3. 參考
1,https://blog.csdn.net/xx326664162/article/details/90756817
2,https://developer.android.com/topic/libraries/architecture/livedata?hl=zh-cn