摘要:方法中,,當為,并且不等于上一次的值,會增加的計數。鎖住當前沒有人在處理任務處理完畢之后將置為首先,采用同步機制,通過有沒有人在處理任務。
說在前面本次推出 Android Architecture Components 系列文章,目前寫好了四篇,主要是關于 lifecycle,livedata 的使用和源碼分析,其余的 Navigation, Paging library,Room,WorkMannager 等春節結束之后會更新,歡迎關注我的公眾號,有更新的話會第一時間會在公眾號上面通知。
Android lifecycle 使用詳解
Android LiveData 使用詳解
Android lifecyle 源碼解剖
Android livedata 源碼解剖
github sample 地址: ArchiteComponentsSample
Android 技術人,一位不羈的碼農。
在前面三篇博客中,我們已經介紹了 lifecycle 的使用及原理,livedata ,ViewModel 的常用用法,今天,讓我們一起來學習 livedata 的原理。
我們先來回顧一下 LiveData 的特點:
LiveData 是一個可以被觀察的數據持有類,它可以感知 Activity、Fragment或Service 等組件的生命周期。
它可以做到在組件處于激活狀態的時候才會回調相應的方法,從而刷新相應的 UI。
不用擔心發生內存泄漏
當 config 導致 activity 重新創建的時候,不需要手動取處理數據的儲存和恢復。內部已經幫我們封裝好了。
當 Actiivty 不是處于激活狀態的時候,如果你想 livedata setValue 之后立即回調 obsever 的 onChange 方法,而不是等到 Activity 處于激活狀態的時候才回調 obsever 的 onChange 方法,你可以使用 observeForever 方法,但是你必須在 onDestroy 的時候 removeObserver
下面,讓我們一步步解剖它
我們知道 livedata 的使用很簡單,它是采用觀察者模式實現的
添加觀察者
在數據改變的時候設置 value,這樣會回調 Observer 的 onChanged 方法
MutableLiveData<String> nameEvent = mTestViewModel.getNameEvent();
nameEvent.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
Log.i(TAG, "onChanged: s = " + s);
mTvName.setText(s);
}
});
observe 方法
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
// 判斷是否已經銷毀
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
// observer 已經添加過了,并且緩存的 observer 跟 owner 的 observer 不一致,狀態異常,拋出異常
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
// 已經添加過 Observer 了,返回回去
if (existing != null) {
return;
}
// 添加 observer
owner.getLifecycle().addObserver(wrapper);
}
首先,我們先來看一下它的 observe 方法,首先通過 owner.getLifecycle().getCurrentState() 獲取狀態,判斷是否已經被銷毀,如果已經被銷毀,直接返回。接著用 LifecycleBoundObserver 包裝起來。然后從緩存的 mObservers 中讀取 observer,如果有,證明已經添加過了。
observe 方法,小結起來就是
判斷是否已經銷毀,如果銷毀,直接移除
用 LifecycleBoundObserver 包裝傳遞進來的 observer
是否已經添加過,添加過,直接返回
將包裝后的 LifecycleBoundObserver 添加進去
因此,當 owner 你(Activity 或者 fragment) 生命周期變化的時候,會回調 LifecycleBoundObserver 的 onStateChanged 方法,onStateChanged 方法又會回調 observer 的 onChange 方法
LifecycleBoundObserverclass LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
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,繼承 ObserverWrapper,實現了 GenericLifecycleObserver 接口。而 GenericLifecycleObserver 接口又實現了 LifecycleObserver 接口。 它包裝了我們外部的 observer,有點類似于代理模式。
GenericLifecycleObserver#onStateChanged
Activity 回調周期變化的時候,會回調 onStateChanged ,會先判斷 mOwner.getLifecycle().getCurrentState() 是否已經 destroy 了,如果。已經 destroy,直接移除觀察者。這也就是為什么我們不需要手動 remove observer 的原因。
如果不是銷毀狀態,會調用 activeStateChanged 方法 ,攜帶的參數為 shouldBeActive() 返回的值。 而當 lifecycle 的 state 為 started 或者 resume 的時候,shouldBeActive 方法的返回值為 true,即表示激活。
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);
}
}
activeStateChanged 方法中,,當 newActive 為 true,并且不等于上一次的值,會增加 LiveData 的 mActiveCount 計數。接著可以看到,onActive 會在 mActiveCount 為 1 時觸發,onInactive 方法則只會在 mActiveCount 為 0 時觸發。即回調 onActive 方法的時候活躍的 observer 恰好為 1,回調 onInactive 方法的時候,沒有一個 Observer 處于激活狀態。
當 mActive 為 true 時,會促發 dispatchingValue 方法。
dispatchingValue
private void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 如果正在處理,直接返回
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
// initiator 不為 null,調用 considerNotify 方法
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else { // 為 null 的時候,遍歷所有的 obsever,進行分發
for (Iterator, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
// 分發完成,設置為 false
mDispatchingValue = false;
}
其中 mDispatchingValue, mDispatchInvalidated 只在 dispatchingValue 方法中使用,顯然這兩個變量是為了防止重復分發相同的內容。當 initiator 不為 null,只處理當前 observer,為 null 的時候,遍歷所有的 obsever,進行分發
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.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
// 數據已經是最新,返回
return;
}
// 將上一次的版本號置為最新版本號
observer.mLastVersion = mVersion;
//noinspection unchecked
// 調用外部的 mObserver 的 onChange 方法
observer.mObserver.onChanged((T) mData);
}
如果狀態不是在活躍中,直接返回,這也就是為什么當我們的 Activity 處于 onPause, onStop, onDestroy 的時候,不會回調 observer 的 onChange 方法的原因。
判斷數據是否是最新,如果是最新,返回,不處理
數據不是最新,回調 mObserver.onChanged 方法。并將 mData 傳遞過去
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
setValue 方法中,首先,斷言是主線程,接著 mVersion + 1; 并將 value 賦值給 mData,接著調用 dispatchingValue 方法。dispatchingValue 傳遞 null,代表處理所有 的 observer。
這個時候如果我們依附的 activity 處于 onPause 或者 onStop 的時候,雖然在 dispatchingValue 方法中直接返回,不會調用 observer 的 onChange 方法。但是當所依附的 activity 重新回到前臺的時候,會促發 LifecycleBoundObserver onStateChange 方法,onStateChange 又會調用 dispatchingValue 方法,在該方法中,因為 mLastVersion < mVersion。所以會回調 obsever 的 onChange 方法,這也就是 LiveData 設計得比較巧妙的一個地方
同理,當 activity 處于后臺的時候,您多次調用 livedata 的 setValue 方法,最終只會回調 livedata observer 的 onChange 方法一次。
postValueprotected void postValue(T value) {
boolean postTask;
// 鎖住
synchronized (mDataLock) {
// 當前沒有人在處理 post 任務
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
AppToolkitTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
// 處理完畢之后將 mPendingData 置為 NOT_SET
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
首先,采用同步機制,通過 postTask = mPendingData == NOT_SET 有沒有人在處理任務。 true,沒人在處理任務, false ,有人在處理任務,有人在處理任務的話,直接返回
調用 AppToolkitTaskExecutor.getInstance().postToMainThread 到主線程執行 mPostValueRunnable 任務。
@MainThread
public void observeForever(@NonNull Observer observer) {
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);
}
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
因為 AlwaysActiveObserver 沒有實現 GenericLifecycleObserver 方法接口,所以在 Activity o生命周期變化的時候,不會回調 onStateChange 方法。從而也不會主動 remove 掉 observer。因為我們的 obsever 被 remove 掉是依賴于 Activity 生命周期變化的時候,回調 GenericLifecycleObserver 的 onStateChange 方法。
liveData 當我們 addObserver 的時候,會用 LifecycleBoundObserver 包裝 observer,而 LifecycleBoundObserver 可以感應生命周期,當 activity 生命周期變化的時候,如果不是處于激活狀態,判斷是否需要 remove 生命周期,需要 remove,不需要,直接返回
當處于激活狀態的時候,會判斷是不是 mVersion最新版本,不是的話需要將上一次緩存的數據通知相應的 observer,并將 mLastVsersion 置為最新
當我們調用 setValue 的時候,mVersion +1,如果處于激活狀態,直接處理,如果不是處理激活狀態,返回,等到下次處于激活狀態的時候,在進行相應的處理
如果你想 livedata setValue 之后立即回調數據,而不是等到生命周期變化的時候才回調數據,你可以使用 observeForever 方法,但是你必須在 onDestroy 的時候 removeObserver。因為 AlwaysActiveObserver 沒有實現 GenericLifecycleObserver 接口,不能感應生命周期。
題外話
Android Architecture Components 已經寫了四篇文章了,其余的 Navigation, Paging library,Room,WorkMannager 等春節結束之后再更新了,歡迎關注我的公眾號,有更新的話會第一時間在公眾好上面更新。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7271.html
摘要:使用詳解使用詳解源碼解剖源碼解剖地址技術人,一位不羈的碼農。在中,它默認為我們初始化,作為一個成員變量。在方法中,它會判斷我們是否已經添加,沒有的話,添加進去。說在前面 本次推出 Android Architecture Components 系列文章,目前寫好了四篇,主要是關于 lifecycle,livedata 的使用和源碼分析,其余的 Navigation, Paging libr...
摘要:前言官方架構組件在今年月份大會上被公布直到月份一直都是測試版由于工作比較繁忙期間我只是看過類似的文章但沒有在實際項目中使用過更沒有看過源碼所以對這幾個組件的使用很是生疏同時也覺得這幾個組件非常高大上非常神秘直到月份官方架構組件正式版發布并且 前言 Android 官方架構組件在今年 5 月份 Google I/O 大會上被公布, 直到 11 月份一直都是測試版, 由于工作比較繁忙, 期...
閱讀 1785·2023-04-26 00:47
閱讀 1543·2021-11-11 16:55
閱讀 2597·2021-09-27 14:04
閱讀 3547·2021-09-22 15:58
閱讀 3554·2021-07-26 23:38
閱讀 2129·2019-08-30 13:47
閱讀 1979·2019-08-30 13:15
閱讀 1141·2019-08-29 17:09