Android Jetpack 架構之 LiveData 源碼分析
1. 認識 LiveData
1.1. LiveData 介紹
引用官方介紹:
LiveData 是一個可觀察的數(shù)據(jù)存儲類,實際上就是一個消息組件,用于數(shù)據(jù)的傳遞。和一般的可觀察者不同的是,LiveData 是具有生命周期感知能力的,意思是它關心其它應用組件的生命周期,如:Activity,F(xiàn)ragment 和 Service。這種感知能力意味著 LiveData 只會更新那些生命周期處于活躍狀態(tài)的應用組件觀察者。
1.2. 使用 LiveData 的優(yōu)勢
引自官方介紹:
- 與生命周期組件關聯(lián),當生命周期組件銷毀后,LiveData 會進行自動清理,所以,不會出現(xiàn)內(nèi)存泄漏。
- 當 Activity 或 Fragment 牌非活躍狀態(tài)時,LiveData 不會為這些處于非活躍狀態(tài)(后面會詳細分析活躍或非活躍狀態(tài))的觀察者發(fā)送數(shù)據(jù),所以,不會導致非活躍的 Activity 或 Fragment 出現(xiàn)崩潰。
- 不需要使用者手動處理生命周期,LiveData 會根據(jù)觀察者不同的生命周期變化而進行相應數(shù)據(jù)的更新。
- 可以全局共享同一個 LiveData 來實現(xiàn)一些特殊的功能。
- Room 數(shù)據(jù)庫原生支持返回 LiveData 封裝后的數(shù)據(jù),方便 LiveData 開發(fā)者操作數(shù)據(jù)庫。
1.3. 傳統(tǒng)消息組件存在的問題
傳統(tǒng)的消息處理組件對開發(fā)的要求較高,對于一些經(jīng)驗欠缺的工程師來說,很容易寫出帶有 Bug 的代碼,導致內(nèi)存泄漏,甚至崩潰。如:系統(tǒng)提供的 Handler 組件,由于隊列中未處理消息持有引用問題,消息處理過程中頁面關閉的內(nèi)存泄漏問題等等;再如:Github 上有名的 Eventbus 消息組件,弱關聯(lián)導致代碼使用混亂難定位問題,需要開發(fā)者自己處理生命周期問題等等。
2. LiveData 總體結構及各自職責
2.1. LiveData 整體架構
上圖是 LiveData 的一個整體架構圖,現(xiàn)在我們來對架構中所涉及到的主要類職責進行說明。
2.2. LiveData
LiveData 是一個抽象類,也是 LiveData 整個設計的核心類。它實際上是一個 Observeable 對象,主要負責數(shù)據(jù)版本的維護、Observer 對象的管理以及消息的分發(fā)等工作。
數(shù)據(jù)版本的維護指的是 LiveData 使用版本來對發(fā)送的消息進行維護,每發(fā)送一次消息,版本自加 1 。這種做的好處是當對應的消息觀察者從不活躍狀態(tài)進入活躍狀態(tài)時,由于每個觀察者也使用了一個版本來維護自己最后一次所接收到的消息的版本,LiveData 在發(fā)送數(shù)據(jù)更新時,只需要拿自己最后更新的版本號與觀察者所持有的版本號進行比對,就能知道是否需要把最后一次更新的數(shù)據(jù)發(fā)送給觀察者。
Observer 對象的管理說的是 LiveData 是一個 Observable 對象,其對象里持有一個 Observer 集合對象,用以對所有的觀察者進行管理。當有新消息傳遞或者相應的組件生命周期發(fā)生變化后,就會通過遍歷集合,并通過觀察者所關聯(lián)的生命周期組件的狀態(tài)來更新滿足更新狀態(tài)的觀察者。
消息分發(fā)指的就是對消息進行集中處理,整個 LiveData 實現(xiàn)中的數(shù)據(jù)處理都是在同一個地方集中處理的。
2.3. MutableLiveData
public class MutableLiveData<T> extends LiveData<T> {
public MutableLiveData(T value) {
super(value);
}
public MutableLiveData() {
super();
}
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
MutableLiveData 是 LiveData 的一個實現(xiàn)類,它里面其實什么也沒有做,只是暴露了兩個傳遞消息的方法,方法的真實實現(xiàn)還是在 LiveData 里面。LiveData 中有很多其它的一些實現(xiàn)類,而這個 MutableLiveData 應該是最簡單的一個實現(xiàn)類,由于在 Kotlin 中所有的對象會分為 mutable 和 immutable 兩種類型,而默認不帶前綴的是 immutable 類型,意思是賦值之后,對應的值不能被改變。此類更多的意思是表示該類是一個可變的 LiveData 對象,也就是可能重復為消息對象賦值。像下面這種情況,就不行。
val text: LiveData<String> = MutableLiveData("aaaa")
text.value="bbb" // compile error
2.4. LifecycleBondObserver
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ignore others ........
}
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
ignore others ........
}
LifecycleBoundObserver 是一個 Observer 對象,繼承自 ObserverWrapper 類。這個 ObserverWrapper 類是一個 Observer 的包裝類。它里面只有三個變量,一個是 observer 表示持有 observer 對象;一個是 mActive 表示當前 Observer 對應的 LiveData 所關聯(lián)的 LifecycleOwner 的狀態(tài),其實就是處于活躍狀態(tài)或不活躍狀態(tài);第三個變量 mLastVersion 表示當前 Observer 的最后更新的版本。
LifecycleBoundObserver 是一個將 LifecycleOwner 與訂閱了 LiveData 對象的 Observer 封裝在一起的一樣類。這樣做的好處是,當 LiveData 的發(fā)送新的數(shù)據(jù)再對消息進行分發(fā)時,直接可以判斷 Observer 所關聯(lián)的 LifeOwner 的生命周期狀態(tài)來決定是否要將數(shù)據(jù)發(fā)送給 Observer 處理。
說到這里,其實有一個比較重要的東西需要說明一下,就是所謂的 LiveData 是具有生命周期感知的消息組件,其本質(zhì)是因為 訂閱了 LiveData 消息的觀察者與具體的具有生命周期特性的這些組件關聯(lián)在了一起,而 LiveData 在分發(fā)消息時,會根據(jù)不同的 Observer 對象所關聯(lián)的 LifecycleOwner 的狀態(tài),來決定是否為該 Observer 分發(fā)數(shù)據(jù)而已。其 LiveData 對象本身只是一個簡單的消息分發(fā)的類。
2.5. ComponentActivity 及其子類
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
ignore ....
}
ComponentActivity 是一個繼承了 LifecycleOwner 的具有生命周期屬性的 Activity 組件。每個 ComponentActivity 及其子類都持有一個 LifecycleRegistry 對象,用于專門處理 ComponentActivity 的生命周期事件及管理訂閱了生命周期組件的觀察者 Observer。ComponentActivity 并不直接管理自己的生命周期,而是通過 ReportFragment 對象來進行管理及分發(fā)的。
2.6. ReportFragment
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
private ActivityInitializationListener mProcessListener;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
....
ReportFragment 對象用于對 ComponentActivity 生命周期進行具體管理及事件分發(fā)的類。每一個 ComponentActivity 在 onCreate 方法里都會創(chuàng)建并將 ReportFragment 對象注冊到其中。這里的設計還是比較巧妙的,使用一個 Fragment 來對 Activity 的生命周期進行管理,我們知道 activity 對應的生命周期發(fā)生變化后,fragment 也會收到相應的回調(diào)。
這種設計我是在 Glide 中有見到過,我們知道 Glide 也是一個具有生命周期感知能力的框架,當我們在創(chuàng)建 Glide 時,使用的是 activity 對象時,當 activity 不可見時,Glide 就會停止處理圖片。
從上面的代碼中可以看出 activity 所對應的幾種生命周期都在 ReportFragment 中得到了重寫,而且里面都有一個dispatch(Lifecycle.Event.XXX) 函數(shù),該函數(shù)主要是做生命周期事件分發(fā)用的。該函數(shù)把生命周期轉發(fā)給 LifecycleRegistry 對象來進行處理。
其實,ReportFragment 除了直接綁定具體的 Activity 做相應的生命周期分發(fā)以外,還有一個任務是和 ProcessLifecycleOwner 對象有關的。大家會不會覺得奇怪,在 ReportFragment 中的 onActivityCreated(),onStart() 和 onResume() 三個方法中怎么都調(diào)用了兩個分發(fā)事件的方法?先賣個官子吧,在對 ProcessLifecycleOwner 進行分析時,我再來講這個問題。
2.7. ProcessLifecycleOwner
public class ProcessLifecycleOwner implements LifecycleOwner {
private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
ActivityInitializationListener mInitializationListener = new ActivityInitializationListener() {
public void onCreate() {
}
public void onStart() {
ProcessLifecycleOwner.this.activityStarted();
}
public void onResume() {
ProcessLifecycleOwner.this.activityResumed();
}
void activityStarted() {
++this.mStartedCounter;
if (this.mStartedCounter == 1 && this.mStopSent) {
this.mRegistry.handleLifecycleEvent(Event.ON_START);
this.mStopSent = false;
}
}
void activityResumed() {
++this.mResumedCounter;
if (this.mResumedCounter == 1) {
if (this.mPauseSent) {
this.mRegistry.handleLifecycleEvent(Event.ON_RESUME);
this.mPauseSent = false;
} else {
this.mHandler.removeCallbacks(this.mDelayedPauseRunnable);
}
}
}
void activityPaused() {
--this.mResumedCounter;
if (this.mResumedCounter == 0) {
this.mHandler.postDelayed(this.mDelayedPauseRunnable, 700L);
}
}
void activityStopped() {
--this.mStartedCounter;
this.dispatchStopIfNeeded();
}
void attach(Context context) {
this.mHandler = new Handler();
this.mRegistry.handleLifecycleEvent(Event.ON_CREATE);
Application app = (Application)context.getApplicationContext();
app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.get(activity).setProcessListener(ProcessLifecycleOwner.this.mInitializationListener);
}
public void onActivityPaused(Activity activity) {
ProcessLifecycleOwner.this.activityPaused();
}
public void onActivityStopped(Activity activity) {
ProcessLifecycleOwner.this.activityStopped();
}
});
}
ProcessLifecycleOwner 也是一個具有生命周期感知的的對象,但有點奇怪的是,在 Android 中不是只有 Activity,Service 和 Fragment 等對象才有生命周期的概念么?這個 ProcessLifecycleOwner 并沒有繼承這幾個類,怎么也是具有生命周期感知的呢?
帶著上面的疑問,我們來分析一下 ProcessLifecycleOwner 是如何實現(xiàn)生命周期感知功能的。
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}
ProcessLifecycleOwner 是在 ProcessLifecycleOwnerInitializer 對象的 onCreate() 方法中初始化的,ProcessLifecycleOwnerInitializer 繼承自 ContentProvider,我們知道在 Android 系統(tǒng)在進行啟動時,ContentProvider 往往是最先被注冊到系統(tǒng)中的。可以看出 ProcessLifecycleOwner 對象也是在系統(tǒng)剛啟動的時候就被創(chuàng)建了。
private static final ProcessLifecycleOwner sInstance = new ProcessLifecycleOwner();
上面的代碼可以看出,ProcessLifecycleOwner 是一個全局靜態(tài)類,其對象只能通過 get() 方法來獲取。在 ProcessLifecycleOwner 的 init() 方法中,又調(diào)用了 attach() 方法。在 attach() 方法中,調(diào)用了 Application 對象的 registerActivityLifecycleCallbacks() 方法,這是一個全局的 Activity 生命周期回調(diào)的監(jiān)聽。
app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.get(activity).setProcessListener(mInitializationListener);
}
@Override
public void onActivityPaused(Activity activity) {
activityPaused();
}
@Override
public void onActivityStopped(Activity activity) {
activityStopped();
}
});
}
在 onActivityCreated() 回調(diào)方法中,mInitializationListener 被注冊到了 ReportFragment 對象里。我們回到 ReportFragment 對象里,可以看到在其 onActivityCreated(),onStart() 和 onResume() 方法中都調(diào)用了相應的 dispatchXXX() 函數(shù),在這個函數(shù)里又回調(diào)了 mInitializationListener 對象里對應的回調(diào)函數(shù)。
兜了一個圈,發(fā)現(xiàn) ProcessLifecycleOwner 的生命周期也是通過 ReportFragmnet 來管理的,當 Activity 的生命周期發(fā)生變化后,會先調(diào)用 ReportFragment 對應的生命周期函數(shù),而在 ReportFragment 對應生命周期函數(shù)中又調(diào)用了 ProcessLifecycleOwner 對象中的 mInitializationListener 回調(diào)函數(shù)。而 mInitializationListener 其實就是
ProcessLifecycleOwner 所對應的生命周期。
ActivityInitializationListener mInitializationListener =
new ActivityInitializationListener() {
@Override
public void onCreate() {
}
@Override
public void onStart() {
activityStarted();
}
@Override
public void onResume() {
activityResumed();
}
};
ProcessLifecycleOwner 的生命周期說明白了。我直接給出結論吧:ProcessLifecycleOwner 其實是一俱全局的具有生命周期感知能力的 LifecycleOwner 對象,我們可以在注冊 LiveData 對象的時候,傳入這個 ProcessLifecycleOwner 對象,以后只要 Activity 頁面發(fā)生變化后,都會通過 ReportFragment 回調(diào)到 mInitializationListener 對應的回調(diào)方法中,在通過 mRegistry 對象 handleLifecycleEvent() 方法來處理這個事件。
有沒有對這個 mInitializationListener 感到奇怪,怎么這里只有三個生命周期回調(diào)方法,而且 onCreate() 方法里還沒有調(diào)用任何方法?
上面我們說了 ProcessLifecycleOwner 是一個全局的具有生命周期感知能力的對象,它的生命周期其實是和 Application 是一樣的。也就是說只要應用還在運行,它的狀態(tài)永遠都不會大于 ON_RESUME 的狀態(tài),而如果應用退出了,它也就不存在了。第二個問題是,onCreate() 里怎么沒有調(diào)用任何方法呢?
void attach(Context context) {
mHandler = new Handler();
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
...
}
原來是在初始化的時候就已經(jīng)執(zhí)行過了 ON_CREATE 狀態(tài)了。而 ProcessLifecycleOwner 又是一個全局靜態(tài)類,以后都不會再創(chuàng)建了,所以回調(diào)方法中就不再需要對 onCreate() 方法進行處理了。
這里有個問題是:ProcessLifecycleOwner 對象既然是一個全局的生命周期感知對象,它的生命周期事件是通過 mInitializationListener 來實現(xiàn)的。那么,訂閱了它的觀察者又保存在哪里呢?我們先看一下這個全局對象在開發(fā)中的使用。
liveData.observe(ProcessLifecycleOwner.get(), Observer { })
進入 observe 方法中,可以看到下面這個調(diào)用:
owner.getLifecycle().addObserver(wrapper);
從這個調(diào)用可以看出,所有的 Observer 對象都保存在了具有生命周期感知能力對象中的 LifecycleRegistry 對象中,我們剛好在 ProcessLifecycleOwner 里看到了 mRegistry 對象。
private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
到這里這個全局的具有生命周期感知能力的對象就已經(jīng)講完了。我們來看一下大概的調(diào)用情況吧(以 onStart 為例)
2.8. LifecycleRegistry
public class LifecycleRegistry extends Lifecycle {
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
private State mState;
private final WeakReference<LifecycleOwner> mLifecycleOwner;
ignore ........
}
LifecycleRegistry 是一個帶生命周期對象(如:activity,fragment)的管理類,主要負責對訂閱了生命周期對象的 Observer 對象進行管理和維護。這里的 observer 和注冊 LiveData 對象的 observer 本質(zhì)上是同一個類,它是在訂閱 LiveData 時一并注冊到 LiveData 所管理的 mObservers 和 LifecycleRegistry 所管理的 mObserverMap 中的。
2.9. ObserverWithState
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
ObserverWithState 是一個封裝了 LifecycleEventObserver 和 mState 兩個對象的類。這個對象是 LifecycleRegistry 對象中對訂閱了具有生命周期感知能力對象的進行管理的一個封裝類。其中,LifecycleEventObserver 對象就是 LifecycleBoundObserver 對象。而這里的狀態(tài)又是什么呢?
其實這個 mState 對應的就是當前 Observer 所綁定的 LifecycleOwner 當前的生命周期,如果發(fā)生變化,這個值也會被修改。而這個狀態(tài)在更新后,是和 LifecycleOwner 所對應的 LifecycleRegistry 中的 mState 的值是一樣的。
走到這里,涉及 LiveData 整個架構中的主要對象就已經(jīng)都講完了。下面我通過一個流程圖把這個簡單的竄一下。
3. Lifecycle 工作原理相關
在看源碼的時候,有沒有感到頭大,LifecycleRegistry 在更新生命周期的時候,并沒有直接將當前的生命周期事件對象賦值給對應的 Observer 對象,而是出現(xiàn)了一個 upEvent(State state),downEvent(State state),getStateAfter(Event event) 等用來更新具體 Observer 對象的生命周期的。在這個單元我們不妨來分析一下和 Lifecycle 更新機制相關的一些東西吧。
3.1. Event 和 State
在分析之前,先要弄清楚兩個基礎的生命周期對象,如下:
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
···
這里的 Event 對應的就是頁面的生命周期,當具體的生命周期被觸發(fā)了,就會使用對應的事件來進行分發(fā)。而 State 表示頁面的一個狀態(tài),是一種包含關系。
DESTROYED
頁面調(diào)用 ON_DESTROY 后的狀態(tài),會在調(diào)用之前修改其狀態(tài)。
INITIALIZED
當 Activity 被創(chuàng)建了,但 ON_CREATE 還未被調(diào)用時的狀態(tài)。
CREATED
頁面調(diào)用了 ON_CREATE 或者 ON_STOP 后的狀態(tài)。
STARTED
頁面調(diào)用了 ON_START 或者 ON_PAUSE 后的狀態(tài)。
RESUMED
頁面調(diào)用了 ON_RESUME 后的狀態(tài)。
上圖畫的是生命周期事件和狀態(tài)的對應關系,看著會更直觀一些。當對應的生命周期執(zhí)行完成后,所對應的區(qū)域就是當前的狀態(tài)。如:ON_START 執(zhí)行后,就是 STARTED 狀態(tài)。
3.2. Lifecycle 狀態(tài)更新
上面講的都相對理論一些,這一節(jié)我們直接面向源碼,從一次事件的變化來看一下具體的處理流程。
這里從 LifecycleRegistry 的 addObserver() 方法說起。
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 將 observer 與其關聯(lián)的 LifecycleOwner 的狀態(tài)進行封裝,默認給初始值
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 將 observer 對象存儲到 mObserverMap 中進行管理和狀態(tài)維護
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
// 說明已經(jīng)訂閱過了,就不在重復執(zhí)行相應的狀態(tài)更新了
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
// 該值主要是判斷是否需要同步已經(jīng)訂閱了 observer
// 的狀態(tài),但這個值有點奇怪,如果不考慮多線程,這個參數(shù)沒什么必要,如果考慮多線程,
// 這里明顯又沒有做多線程的處理
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
// 正常添加的話,該值就是 LifecycleRegistry 中 mstate 的值
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
// 這個循環(huán)主要是將先加入的 observer 與當前 LifecycleRegistry 的 mstate 進行比較,
// 如果狀態(tài)小于 mState,就會依次按照 Event 事件的先后順序依次對新加入的 observer 進行更新,
// 并分發(fā)事件給 Observer,Observer 最終是否會收到 LiveData 的更新數(shù)據(jù),取決于雙方的數(shù)據(jù)版本號
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// 這個同步方法的作用主要是對已經(jīng)訂閱了 LifecycleOwner 事件的 Observer 對象進行狀態(tài)同步,
// 也就是同步到和 LifecycleRegistry 的 mState 狀態(tài)一致。
sync();
}
mAddingObserverCounter--;
}
當 LiveData 被訂閱之后,就會調(diào)用管理 LifecycleOwner 生命周期對象 LifecycleRegistry 中的 addObserver() 方法,這個方法里做了下面幾件事情:
- 給 Observer 對象綁定 mState 對象,并賦予初始狀態(tài)存入到集合中。
- 更新新加入進入的 Observer 對應的 mState 狀態(tài),這里主要是和當前的 LifecycleRegistry 中的 mState 對象比較后,依次按照 State 中的狀態(tài)對 Observer 進行 Event 生命周期事件分發(fā)。
- 對之前已經(jīng)訂閱了 LifecycleOwner 的 Observer 對象進行狀態(tài)刷新,也就是將 Observer 對象和 LifecycleRegistry 中的狀態(tài)進行同步。
接下來看一下,當頁面的生命周期改變后,具體是怎么處理的。這里拿事件執(zhí)行了 ON_RESUME 為例來分析一下更新過程。
我們可以直接從 ReportFragment 中的 onResume() 看起。
@Override
public void onResume() {
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
}
這里 dispatch() 方法就是分發(fā)生命周期事件的方法。dispatchResume() 是用于為訂閱了全局生命周期事件的 Observer 分發(fā)事件的方法。
private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
// 這里只是為了兼容老的thsg版本用的,LifecycleRegistryOwner
// 在新的 Lifecycle 組件中被標記為了 @Deprecated
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
可以看到這里直接調(diào)用到了當前生命周期的管理類 LifecycleRegistry 的 handleLifecycleEvent(event) 方法。
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
這個方法里只做了一件事情,就是將當前事件轉換為對應的 State 后,就直接調(diào)用了 moveToState() 方法。
private void moveToState(State next) {
if (mState == next) {
return;
}
// 將 lifecycleRegistry 中 mState 對象更新y最新的狀態(tài)
mState = next;
// 這里的判斷與 addObservers() 方法中的判斷是一致的。
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
// 刷新已經(jīng)訂閱了生命周期事件的所有 Observers
sync();
mHandlingEvent = false;
}
這個方法主要是對已經(jīng)訂閱了當前生命周期事件的所有 Observers 對象進行刷新。對單個 Observer 事件的刷新主要是調(diào)用了 ObserverWithState 中的 dispatchEvent() 方法。
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
這個方法首先將當前事件轉換為了對應的 State 狀態(tài)。這里我講一下 min(mState, newState) 這個方法具體是怎么比較的。
static State min(@NonNull State state1, @Nullable State state2) {
return state2 != null && state2.compareTo(state1) < 0 ? state2 : state1;
}
這個比較方法的核心主要是 Enum 對象的比較方法 compareTo(),每個 Enum 對象中都有一個 ordinal 字段,這里的比較操作主要是 ordinal 值的比較。默認情況下,Enum 中對象的 ordinal 是從 0 開始的,依次進行賦值。也就是說上面的對象在比較的時候,是小于下面的對象的。
接下來就調(diào)用了 ```onStateChanged()`` 方法。
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
如果當前狀態(tài)是 DESTROYED,說明該生命周期對象已經(jīng)被銷毀了,對應的 observers 都會被清除。如果是其它狀態(tài),就調(diào)用 activeStateChanged(shouldBeActive()) 方法。
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
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);
}
}
如果狀態(tài)一樣就直接返回。如果當前 Observer 對象所訂閱的 LiveData 對象中的其它所有 Observer 對象都是未激活狀態(tài),也就是 mActiveCount 值等于 0,而當前又是激活分發(fā)的又是激活狀態(tài)的話,就會回調(diào) LiveData 對象的 onActive() 方法。相反,如果當前分發(fā)的是非激活狀態(tài),而更新了 mActiveCount 值后,mActiveCount 值為 0 ,則回調(diào) LiveData 的 onInactive() 方法。這里的兩個方法只有在繼承了 LiveData 并覆寫后,才會收到調(diào)用,LiveData 本身是空實現(xiàn)。
最后,如果分發(fā)的是激活狀態(tài)的話,就會調(diào)用 dispatchingValue() 方法來分發(fā) LiveData 中的值。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 同時只能有一個調(diào)用源執(zhí)行該方法,當然,如果在多線程情況下,是有問題的
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
// initiator 只有在調(diào)用 setValue 更新 LiveData 值的時候,才會為 null
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());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
首先,該方法同時只能被調(diào)用一次。只有在調(diào)用 setValue 更新 LiveData 值的時候,initiator 才會為 null,而我們這里是通過生命周期改變后調(diào)用的,所以,是不為 null 的,這里調(diào)用 considerNotify(initiator) 方法。
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
該方法也比較簡單,只是做了一些必要的判斷。如果當前 observer 對象的 mLastVersion 值大于等于 mVersion,說明當前 observer 對象已經(jīng)是最新的值了,不需要再次更新。如果數(shù)據(jù)版本小于 LiveData 對象的 mVersion,則將當前 LiveData 最新的版本賦值給當前 observer 對象,并將最新的值傳遞給 observer 對象,進行更新。
到這里整個由事件改變后,LiveData 數(shù)據(jù)的更新過程就已經(jīng)結束了。
4. LiveData 訂閱及數(shù)據(jù)更新
4.1. LiveData 訂閱過程
這里再來竄一下 LiveData 的訂閱過程。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
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;
}
owner.getLifecycle().addObserver(wrapper);
}
如果訂閱當前 LiveData 對象所指定的生命周期感知對象的狀態(tài)已經(jīng)是 DESTROYED,就直接返回。接下來使用 LifecycleBoundObserver 對 observer 進行包裝,這個對象里將生命周期對象 mOwner,觀察者對象 mObserver,當前是否處于激活狀態(tài) mActive 以及當前數(shù)據(jù)的版本 mLastVersion 綁定在了一起。并將該包裝對象添加到了 LiveData 管理 Observer 對象的集合類中。同時這里還將包裝對象添加到了 LifecycleRegistry 中用于添加對事件改變的監(jiān)聽。
訂閱過程挺簡單的,接下來我們再來看看對 LiveData 設置值之后的過程。
4.2. LiveData 數(shù)據(jù)更新
LiveData 的數(shù)據(jù)更新主要是通過 setValue() 方法和 postValue() 方法來進行更新的。而 postValue() 方法和 setValue() 的區(qū)別主要是:postValue() 方法主要是用于子線程的數(shù)據(jù)更新,在方法里有切換到主線程去執(zhí)行任務的。所以,這里只需要看 setValue() 方法就可以了。
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
這里只是更新了 LiveData 的版本和數(shù)據(jù)后,就直接調(diào)用到 dispatchingValue(null) 方法了。
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
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());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
這個方法上面講過,只不過上面?zhèn)鬟f的是有值的情況,這里傳的是 null,所以我們走到了另外一個分支。實際上也沒啥就是遍歷了當前所有訂閱了 LiveData 對象的集合類,依次對每個訂閱對象進行數(shù)據(jù)的分發(fā)。
這里有一個問題可以研究一下,就是 mDispatchingValue 和 mDispatchInvalidated 兩個對象是怎么工作的?當?shù)谝淮握{(diào)用 dispatchingValue() 方法的時候,mDispatchingValue 為 true, mDispatchInvalidated 為 false,所以 do ... while 循環(huán)只會被執(zhí)行一次,且 for 循環(huán) 會被執(zhí)行完成。而如果還在 for 循環(huán) 的時候該方法又被調(diào)用了,for 循環(huán) 就會被停止,且新調(diào)用的方法也得不到執(zhí)行。感覺是一種多線程的保護,但看上去很雞肋。
5. 結語
好了,到這里所有關于 LiveData 的分析就已經(jīng)講完了,整個源碼分析并不是很難。LiveData 本身的實現(xiàn)比較簡單,只是如何具備生命周期感知能力的這一部分關于 lifecycle 及其交互的實現(xiàn)稍稍復雜一點,要理清楚他們之間的關系及交互。整個架構的設置還是很優(yōu)秀的,各自的職責非常清晰,生命周期事件與相應狀態(tài)及其更新方式的設計也非常的巧妙,整個架構我用一個雙觀察者的事件驅(qū)動模式來概括。