2.1.LiveData是google官方架構(gòu)JetPack系列的一個響應(yīng)式開發(fā)框架(響應(yīng)式開發(fā)是一種專注于數(shù)據(jù)流和變化傳播的聲明式編程范式),LiveData是一個可以被觀察的數(shù)據(jù)持有者類。LiveData主要用于搭建MVVM架構(gòu),并在其中作為數(shù)據(jù)持有者,LiveData能監(jiān)聽組件的生命周期變化,這樣一來只會更新處于活躍狀態(tài)的組件,一般搭配ViewModel使用,也可以通過Application或者單例進行使用。
LiveData的特點:
1)采用觀察者模式自動提示UI更新。
2)不需要手動處理生命周期,不會因為Activity的銷毀重建而丟失數(shù)據(jù)。
3)不會出現(xiàn)內(nèi)存泄漏。
4)不需要手動取消訂閱,Activity在非活躍狀態(tài)下(銷毀、finish之后)不會收到數(shù)據(jù)更新信息。
5)避免了由Activity處于stop狀態(tài)而引起的崩潰
6)屏幕發(fā)生旋轉(zhuǎn)或回收時也能立即取到數(shù)據(jù),避免了界面由生命周期而出現(xiàn)的問題
? 一般使用MutableLiveData(Mutable可變的),它是LiveData的實現(xiàn)類,LiveData是一個抽象類。
2.2.LiveData使用步驟
在ViewModel中創(chuàng)建一個持有某種數(shù)據(jù)類型的LiveData ,通常是用子類MutableLiveData定義
通過 observe 方法可以訂閱修改數(shù)據(jù)的通知
通過 postValue()或者 setValue()(主線程) 方法發(fā)送事件更新數(shù)據(jù)
已經(jīng)訂閱的 Observer 就能夠得到數(shù)據(jù)更改時的通知并回調(diào) onChanged() 方法
在onChanged()方法中更新數(shù)據(jù)更新UI
舉個簡單例子:

2.3.源碼分析
LiveData主要是觀察者模式實現(xiàn),我們先看看LiveData中observe()方法的參數(shù)

我們看到LiveData源碼中observe()方法第一個參數(shù)是 LifecycleOwner,而我們代碼中傳遞的是當前頁面上下文this,this 和 LifecycleOwner 有何關(guān)系呢
我們順著頁面的Activity進行追蹤如下:




這時候大家發(fā)現(xiàn)了,Activity 的終極父類其實是實現(xiàn)了 LifecycleOwner 的接口,所以傳遞this不會報錯。而observe()的第一個參數(shù)其實就相當于一個被觀察者,第二個參數(shù)observer就相當于觀察者。
除了Activity還有Fragment,Service(具體使用LifecycleService)也都可以進行傳參


分析完observe()的構(gòu)造方法,接下來我們看看observe()方法做了哪些操作
1.首先assertMainThread方法

我們可以查看他的源碼發(fā)現(xiàn): 這個個方法中判斷了當前線程是否為主線程,如果不是主線程則拋出異常
2. if()判斷生命周期狀態(tài)
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
? ? ? ? ? ? // ignore
? ? ? ? ? ? return;
? ? ? ? }
通過owner獲取到當前頁面的生命周期狀態(tài)是否被銷毀,如果銷毀則return,可以避免內(nèi)存泄漏的情況
3.LifecycleBoundObserver裝飾器
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
相當于一個裝飾器,將持有者(被觀察者Activity)和觀察者都裝進去


這里的onStateChanged方法執(zhí)行是通過Lifecycle(生命周期感知組件,它感知的一般是 Activity 和 Fragment 的生命周期,它設(shè)計的目的就是用來管理 Activity 和 Fragment 的生命周期,以減少內(nèi)存泄露甚至崩潰的異常問題的出現(xiàn))回調(diào)執(zhí)行的。
然后我們看判斷是否活躍的的判斷




這個判斷是否是活躍的狀態(tài)是根據(jù)當前的頁面至少是start(或者resume)狀態(tài)來確定,通過enum的ordinal對比比較大小
這里也特別說一聲LiveData具有粘性事件,即被監(jiān)聽者先發(fā)送事件,監(jiān)聽者還未創(chuàng)建(頁面還未創(chuàng)建,事件發(fā)出,然后頁面創(chuàng)建,依然會接受到事件的情況),重點的邏輯代碼為下面:

頁面生命周期變?yōu)榛钴S狀態(tài)然后執(zhí)行dispatchingValue(this)進行監(jiān)聽變更。
4.ObserverWrapper緩存
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);

mObservers是一個Map,相當于緩存,緩存一份裝飾器,key為observer,value為裝飾器wrapper
整個LiveData都是時刻去觀察生命周期的狀態(tài),從而從根源上避免了內(nèi)存泄漏的出現(xiàn),這也是目前好多公司采用jetpack的原因
LiveData中setValue()源碼解析

mVersion
LiveData內(nèi)維護的mVersion表示的是發(fā)送信息的版本,每次發(fā)送一次信息, 它都會+1, 而ObserverWrapper內(nèi)維護的mLastVersion為訂閱觸發(fā)的版本號, 當訂閱動作生效的時候, 它的版本號會和發(fā)送信息的版本號同步.他們初始值都為-1。
static final int START_VERSION = -1;


我們繼續(xù)查看dispatchingValue()的源碼


為什么onChanged可以調(diào)用


observer.mObserver.onChanged((T) mData);
mData即為改變的數(shù)據(jù),通過mObserver調(diào)用onChange(mData),這時候數(shù)據(jù) data 就回到了 onChanged()方法中了。

LiveData 內(nèi)部實現(xiàn)了觀察者模式,如果數(shù)據(jù)要同時通知幾個界面,可以采取這種方式
LiveData 數(shù)據(jù)變化的時候,會回調(diào) Observer 的 onChange 方法,但是回調(diào)的前提是 lifecycleOwner(即所依附的 Activity 或者 Fragment) 處于 onStart() 或者 onResume() 狀態(tài),它才會回調(diào),否則,必須等到 lifecycleOwner 切換到前臺的時候,才回調(diào),其內(nèi)部解決了因為Lifecycle而導(dǎo)致的崩潰,內(nèi)存泄漏等問題。因此,這對性能方面確實是一個不小的提升。
備注:postValue如何在子線程調(diào)用使用




onActive(活躍的)? onInactive(不活躍的) 外部繼承LiveData類可調(diào)用監(jiān)聽當前狀態(tài)是否是活躍的。