LiveData is a data holder class that can be observed within a given lifecycle.
正如注釋所說,LiveData是一個(gè)數(shù)據(jù)持有容器辱挥,并且該容器可以感知生命周期的變化,在合適的時(shí)機(jī)通知觀察者數(shù)據(jù)的變更啊央。
首先定義幾個(gè)名詞眶诈,LifecycleOwner owner
這里暫且稱之為生命周期感知者
,簡(jiǎn)稱感知者
吧瓜饥,Observer<? super T> observer
是外部傳入的回調(diào)接口逝撬,內(nèi)部會(huì)被包裝成ObserverWrapper
,在此稱之為觀察者
乓土。
LiveData
是一個(gè)抽象類宪潮,其子類常用的有MutableLiveData
,MediatorLiveData
和RoomTrackingLiveData
趣苏。繼承關(guān)系如下:
public abstract class LiveData<T> {}
// 只是開放了postValue(T value)和setValue(T value)數(shù)據(jù)操作方法
public class MutableLiveData<T> extends LiveData<T> {}
// 依賴監(jiān)聽其他或多個(gè)LiveData的變化
public class MediatorLiveData<T> extends MutableLiveData<T> {}
// Room Database框架狡相,暫不分析
class RoomTrackingLiveData<T> extends LiveData<T> {}
一般情況下,首先會(huì)構(gòu)造一個(gè)LiveData
對(duì)象食磕,然后注冊(cè)一個(gè)LifecycleOwner
生命周期感知者(一般是Fragment
或者Activity
)和數(shù)據(jù)變化通知的回調(diào)接口尽棕,內(nèi)部把回調(diào)接口包裝成觀察者ObserverWrapper
:
一般請(qǐng)用步驟:
LiveData<User> liveData = new MutableLiveData();
liveData.observe(this, new Observer<User>() {
@Override
public void onChanged(User user) {
// do something with the newest data
}
});
<LiveData.java>
static final int START_VERSION = -1;
private int mVersion;// 這個(gè)值是用于判斷是否已經(jīng)通知過,保證每次通知都是最新的數(shù)據(jù)值
public LiveData(T value) {
mData = value;
mVersion = START_VERSION + 1;// 默認(rèn)0開始彬伦,因?yàn)樵摌?gòu)造默認(rèn)已經(jīng)將數(shù)據(jù)賦值
}
public LiveData() {
mData = NOT_SET;
mVersion = START_VERSION;// 默認(rèn)-1開始
}
注意observe
必須在主線程調(diào)用滔悉,接著看下observe
方法中的實(shí)現(xiàn):
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 檢查是否在主線程
assertMainThread("observe");
// 如果當(dāng)前感知者的生命周期處于Destroy狀態(tài),直接忽略
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// 將感知者和回調(diào)接口包裝成觀察者對(duì)象单绑,具備感知生命周期和觸發(fā)外部回調(diào)的功能
// 生命周期感知也是一種觀察者模型
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 一種類似Map的數(shù)據(jù)結(jié)構(gòu)回官,緩存當(dāng)前觀察者
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
// 一個(gè)回調(diào)接口只能綁定一個(gè)觀察者
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
// 同一個(gè)觀察者只能添加一次
if (existing != null) {
return;
}
// 添加生命周期監(jiān)聽
owner.getLifecycle().addObserver(wrapper);
}
這個(gè)LifecycleBoundObserver
觀察者中實(shí)現(xiàn)了LifecycleObserver
,具備生命周期的感知能力:
// 對(duì)生命周期變化觀察者的封裝
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
// 感知者
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
// 生命周期在onStart之后才會(huì)被標(biāo)記為激活狀態(tài)
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
// 生命周期狀態(tài)變更回調(diào)
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
// 如果感知者的生命周期進(jìn)入destroy搂橙,則移除該觀察者(同時(shí)釋放了該感知者)歉提,避免內(nèi)存泄漏
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
// 通知狀態(tài)變更(改變父類的mActive變量值),在分發(fā)通知時(shí)會(huì)用于判斷
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
// 移除生命周期監(jiān)聽
mOwner.getLifecycle().removeObserver(this);
}
}
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;// 是否可見激活狀態(tài)
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();// 是否被激活份氧,LifecycleBoundObserver中onStart之后為true
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;
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);
}
}
}
接著,如果我們需要改變LiveData中的數(shù)據(jù)時(shí)弯屈,只需調(diào)用其setValue或者postValue方法:
// 緩存數(shù)據(jù)對(duì)象
private volatile Object mData;
// setValue只能在主線程調(diào)用
@MainThread
protected void setValue(T value) {
// 判斷線程
assertMainThread("setValue");
// 標(biāo)記操作數(shù)
mVersion++;
// 賦值數(shù)據(jù)
mData = value;
// 分發(fā)通知各個(gè)觀察者
dispatchingValue(null);
}
// 只是切換線程的作用蜗帜,可以在子線程調(diào)用
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
// 緩存當(dāng)前改變的數(shù)據(jù)
// 在runnable中會(huì)重新標(biāo)記為NOT_SET,避免并發(fā)問題
mPendingData = value;
}
if (!postTask) {
return;
}
// 該runnable最終還是會(huì)調(diào)用setValue
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
典型的觀察者模式资厉,接下去就是通知各個(gè)觀察者數(shù)據(jù)的變化了:
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// mDispatchingValue第一次默認(rèn)false
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
// mDispatchingValue賦值true
// 此時(shí)如果下一次setValue觸發(fā)厅缺,上面的mDispatchInvalidated變?yōu)閠rue,下面for循環(huán)打斷退出宴偿,并且重新執(zhí)行do-while循環(huán)湘捎,這樣就能保證再次分發(fā)通知是最新的數(shù)據(jù)值(這幾個(gè)標(biāo)記的boolean變量主要也是處理并發(fā)問題)
mDispatchingValue = true;
do {
mDispatchInvalidated = false;// 默認(rèn)只會(huì)執(zhí)行一次do-while循環(huán)
if (initiator != null) {
// 當(dāng)一個(gè)observer從非激活到激活狀態(tài)時(shí)會(huì)進(jìn)入該分支
// 該分支只會(huì)通知該observer
considerNotify(initiator);
initiator = null;
} else {
// 一般進(jìn)入該分支
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
// 遍歷取出集合中的ObserverWrapper進(jìn)行通知
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {// 如果數(shù)據(jù)在遍歷期間有新的變更,則后面未通知到觀察者不再通知
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
// 通知觀察者數(shù)據(jù)變化
private void considerNotify(ObserverWrapper observer) {
// 觀察者是否處于生命周期可見狀態(tài)窄刘,mActive默認(rèn)為false不進(jìn)行通知窥妇,但是在LifecycleObserver生命周期onStart之后會(huì)賦值true
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.
// 再次檢查observer的生命周期是否onStart之后
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// mLastVersion默認(rèn)為-1,一般mVersion在LiveData的構(gòu)造方法中賦值-1
// 另外一個(gè)構(gòu)造中賦值0娩践,在setValue中會(huì)++變?yōu)?或者1
// 保證同一個(gè)observer對(duì)象對(duì)該次數(shù)據(jù)變化只能接收一次通知
if (observer.mLastVersion >= mVersion) {
// 如果version相等活翩,表示該數(shù)據(jù)已經(jīng)通知過了
return;
}
// 標(biāo)識(shí)該次數(shù)據(jù)變化已經(jīng)通知過了
observer.mLastVersion = mVersion;
//noinspection unchecked
// 回調(diào)通知
observer.mObserver.onChanged((T) mData);
}
// 對(duì)于從非激活狀態(tài)到激活狀態(tài)烹骨,會(huì)主動(dòng)請(qǐng)求接收通知
private abstract class ObserverWrapper {
...
void activeStateChanged(boolean newActive) {
// 生命周期狀態(tài)沒變,忽略
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
// 是否不存在激活狀態(tài)的observer
boolean wasInactive = LiveData.this.mActiveCount == 0;
// 如果observer生命周期激活狀態(tài)材泄,激活的observer數(shù)量+1沮焕,否則-1
LiveData.this.mActiveCount += mActive ? 1 : -1;
// 一般情況可以忽略該判斷
if (wasInactive && mActive) {
onActive();// 回調(diào)通知,MediatorLiveData中有實(shí)現(xiàn)
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();// 回調(diào)通知拉宗,MediatorLiveData中有實(shí)現(xiàn)
}
// 如果從未激活到激活峦树,會(huì)重新分發(fā)一次
if (mActive) {
dispatchingValue(this);
}
}
}
代碼不多,內(nèi)部就是一個(gè)典型的觀察者模型旦事,主要核心是在通知觀察者的過程中引入了生命周期的感知魁巩,對(duì)于處于激活狀態(tài)的observer才進(jìn)行通知更新,當(dāng)observer從非激活到激活狀態(tài)也會(huì)收到通知族檬。重點(diǎn)是在observer生命周期結(jié)束(Destroy)時(shí)歪赢,會(huì)自動(dòng)釋放observer的引用,從而避免了內(nèi)存泄漏单料。
最后編輯于 :2019.12.26 21:50:14
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者