LiveData源碼分析
LiveData是Android提供的監聽資料更新的架構,它能夠感應Activity/Fragment的生命周期,接下來的内容我們來通過簡單的用法去探索LiveData源碼的核心知識點。
LiveData感應生命周期的核心
Android涉及到生命周期的時候,基本都是和Lifecycle類有關,我們先來看一下
**LiveData.observe(LifecycleOwner owner, @NonNull Observer<? super T> observer)**裡面的代碼:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
...
...
owner.getLifecycle().addObserver(wrapper);
}
Lifecycle是谷歌提供的用來監聽Activity與Fragment的生命周期變化,Lifecycle提供了兩個接口:
- LifeCycleOwner 生命周期的擁有者,也就是Activity/Fragment,其Android源碼Activity一般都繼承這個接口
- LifeCycleObserver 生命周期的觀察者,可以是任何類,常見的有MVP的P
上面簡單的講解了Lifecycle的作用,回到上面那段代碼,我們可以看到,當檢測到目前是生命周期是DESTROYED的時候,直接忽略掉,不進行添加任何監聽器。
接下來我們再看看LifecycleBoundObserver類:
class LifecycleBoundObserver extends ObserverWrapper
LifecycleBoundObserver類是ObserverWrapper抽象類的子類:
private abstract class ObserverWrapper {
....
// 是否激活狀态
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
//分離監聽
void detachObserver() {
}
//激活狀态改變
void activeStateChanged(boolean newActive) {
....
}
}
可以看到,ObserverWrapper抽象類主要是定義了一些固定的規範,然後我們看看LifecycleBoundObserver類的代碼:
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
// 隻有大于Start狀态才是激活狀态
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
// 目前是DESTROYED狀态的時候直接不處理,并删除監聽
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);
}
}
LifecycleBoundObserver是一個包裝類,是對LifeCycleOwner和LifeCycleObserver的組合。
是以我們總結一下:
LiveData是通過Lifecycle來感應生命周期的,當Activity/Fragment在Start和Destory之間時,才會發送更新資訊,否則不進行更新,想要更具體的了解這一塊内容,還是得往下看。
LiveData注冊監聽器
LiveData用監聽的處理分兩種:
- 能夠感應生命周期
- 不考慮感應生命周期
我們先來看看能夠感應生命周期的代碼段:
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 1.0檢測目前是否是主線程
assertMainThread("observe");
// 2.0目前是DESTROYED狀态,直接忽略
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
// 3.0把生命周期擁有者和觀察者包裝起來
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 4.0 以Map的結構添加包裝類,然後判斷是否已經添加過了,已經添加則抛出異常
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;
}
// 5.0将監聽者添加到相應位置
owner.getLifecycle().addObserver(wrapper);
}
總結流程如下:
- 檢測目前是否是主線程
- 目前是DESTROYED狀态,直接忽略
- 把生命周期擁有者和觀察者包裝起來
- 以Map的結構添加包裝類,然後判斷是否已經添加過了,已經添加則抛出異常
- 将監聽者添加到相應位置
然後我們再看看不考慮感應生命周期的代碼段:
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
可以看到不考慮感應生命周期的時候,基本流程和感應生命周期的一緻,隻是使用了不同的ObserverWrapper抽象類的包裝子類,我們來看看AlwaysActiveObserver的代碼:
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
從AlwaysActiveObserver類中的激活狀态是永遠傳回True的,那麼說明其永遠都是激活态。
LiveData發送更新資料資訊
LiveData提供了兩個方法進行更新資料:
- postValue:非主線程更新資料
- setValue:必須在主線程才能更新資料,否則會抛出異常
我們先看看LiveData.postValue的代碼:
protected void postValue(T value) {
boolean postTask;
1.0 加鎖,并把value指派給全局變量mPendingData
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
2.0 判斷mPendingData是否已經完成之前的任務
if (!postTask) {
return;
}
3.0 切換到主線程執行任務
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
4.0 把mPendingData全局變量指派給局部變量,然後把mPendingData恢複初始狀态
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
5.0 設定更新值
setValue((T) newValue);
}
};
從上面的代碼,我們可以總結出,LiveData.postValue主要是做了線程的切換工作,最終還是由LiveData.setValue來完成資料的更新提醒:
protected void setValue(T value) {
assertMainThread("setValue");
//版本+1
mVersion++;
// 全局變量儲存需要更新的值
mData = value;
dispatchingValue(null);
}
void dispatchingValue(@Nullable ObserverWrapper initiator) {
...
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());
...
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private void considerNotify(ObserverWrapper observer) {
// 不是激活狀态不處理
if (!observer.mActive) {
return;
}
// 判斷是不處于激活狀态
if (!observer.shouldBeActive()) {
// 通知激活狀态改為false
observer.activeStateChanged(false);
return;
}
// 監聽者的版本号大于目前的版本号不分發
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
// 通知資料的更新
observer.mObserver.onChanged((T) mData);
}
總結整個更新值通知的流程就是:
- 切換線程更新值
- 根據ObserverWrapper開發逐個監聽者分發
- 分發的時候要剔除不是激活态的和老版本的不分發