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源碼一般都繼承這個接口
- 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開發逐個監聽者分發
- 分發的時候要剔除不是激活態的和老版本的不分發