上一篇咱們分析了
Lifecycles
組件的源碼,本篇咱們將繼續分析LiveData
組件java
相關係列文章:git
1. Jetpack源碼解析---看完你就知道Navigation是什麼了?github
2. Jetpack源碼解析---Navigation爲何切換Fragment會重繪?app
3. Jetpack源碼解析---用Lifecycles管理生命週期異步
LiveData
是一個可觀察的數據持有者類,與常規observable
不一樣,LiveData
是生命週期感知的,這意味着它尊重其餘應用程序組件的生命週期,例如Activity
,Fragment
或Service
。此感知確保LiveData
僅更新處於活動生命週期狀態的應用程序組件觀察者。ide
1. 確保UI符合數據狀態 LiveData遵循觀察者模式。 當生命週期狀態改變時,LiveData會向Observer發出通知。 您能夠把更新UI的代碼合併在這些Observer對象中。沒必要去考慮致使數據變化的各個時機,每次數據有變化,Observer都會去更新UI。函數
2. 沒有內存泄漏 Observer會綁定具備生命週期的對象,並在這個綁定的對象被銷燬後自行清理。源碼分析
3. 不會因中止Activity而發生崩潰 若是Observer的生命週期處於非活躍狀態,例如在後退堆棧中的Activity,就不會收到任何LiveData事件的通知。post
4.不須要手動處理生命週期 UI組件只須要去觀察相關數據,不須要手動去中止或恢復觀察。LiveData會進行自動管理這些事情,由於在觀察時,它會感知到相應組件的生命週期變化。ui
5. 始終保持最新的數據 若是一個對象的生命週期變到非活躍狀態,它將在再次變爲活躍狀態時接收最新的數據。 例如,後臺Activity在返回到前臺後當即收到最新數據。
6. 正確應對配置更改 若是一個Activity或Fragment因爲配置更改(如設備旋轉)而從新建立,它會當即收到最新的可用數據。
7.共享資源 您可使用單例模式擴展LiveData對象幷包裝成系統服務,以便在應用程序中進行共享。LiveData對象一旦鏈接到系統服務,任何須要該資源的Observer都只需觀察這個LiveData對象。
在咱們的Jetpack_Note中有使用demo,具體可查看LiveDataFragment。 Demo中經過對一個LiveData對象進行生命週期的監聽,實現將值打印在控制檯中。首先聲明一個LiveData對象:
private lateinit var liveData: MutableLiveData<String>
複製代碼
點擊開始觀察數據按鈕,彈出控制檯,咱們能夠看到控制檯輸出了onStart()
日誌,由於咱們將liveData的值和Fragment的生命週期進行了綁定,當返回桌面或者銷燬Fragment的時候,LiveData的值會變成相應的生命週期函數,並打印在控制檯中:
class LiveDataFragment : Fragment() {
private lateinit var liveData: MutableLiveData<String>
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? {
return inflater.inflate(R.layout.fragment_live_data, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
liveData = MutableLiveData()
btn_observer_data.setOnClickListener {
if (FloatWindow.get() == null) {
FloatWindowUtils.init(activity?.application!!)
}
FloatWindowUtils.show()
//建立一個觀察者去更新UI
val statusObserver = Observer<String> { lifeStatus ->
FloatWindowUtils.addViewContent("LiveData-onChanged: $lifeStatus")
}
liveData.observeForever(statusObserver)
}
}
override fun onStart() {
super.onStart()
liveData.value = "onStart()"
}
override fun onPause() {
super.onPause()
liveData.value = "onPause()"
}
override fun onStop() {
super.onStop()
liveData.value = "onStop()"
}
override fun onDestroy() {
super.onDestroy()
liveData.value = "onDestroy()"
}
}
複製代碼
**注意:**這裏我使用了
observeForever
監聽了全部生命週期方法,因此你會看到onDestroy()等生命週期函數的打印。
好了,Demo很簡單,接下來咱們來看一下源碼,進行分析:
咱們聲明瞭一個LiveData
對象,並經過監聽Fragment
的生命週期來改變LiveData
中的value值,LiveData
實際上就像一個容器,Demo中存儲了一個String類型的值,當這個值發生改變的時候,能夠在回調中監聽到他的改變。接下來咱們就先從addObserver
入手:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
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);
}
複製代碼
查看源碼,咱們調用observer()
時,傳遞了兩個參數,第一個是LifecycleOwner
接口實例,而咱們繼承的Fragment
自己就已經實現了這個接口,因此咱們傳this
便可;第二個參數Observer
就是咱們觀察的回調。接下來將這兩個參數傳遞new出了一個新的對象:LifecycleBoundObserver
,最後將LifecycleBoundObserver
和LifecycleOwner
進行了綁定,其實這裏面咱們能夠將LifecycleOwner
就理解成咱們的Fragment
或者Activity
的實例,由於它們都實現了LifecycleOwner
。
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
.....
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
//Activity生命週期變化時,回調方法
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//更新livedata活躍狀態
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
//解除監聽
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
複製代碼
咱們能夠看到這裏面與LifecycleOwner
進行了綁定,而且實現了onStateChanged
方法,當生命週期發生變化時執行activeStateChanged(shouldBeActive());
方法;shouldBeActive()
返回了 要求生命週期至少是STARTED狀態才被認爲是activie狀態;若是state是DESTROYED
狀態時,解綁LifecycleOwner
和LiveData
。接下來咱們看下怎樣更新livedata中數據值:
咱們追蹤activeStateChanged
方法發現,在裏面作了一些活躍狀態值的操做,而且當狀態活躍時,更新數據值:
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);
}
}
複製代碼
void dispatchingValue(@Nullable ObserverWrapper initiator) {
...
//遍歷LiveData的全部觀察者執行下面代碼
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
...
}
//將數據值回調到livedata.observer()回去
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);
}
複製代碼
從上面咱們能夠看到LiveData
的數據更新以及數據回調的整個過程,可是當咱們手動setValue()
的時候過程是怎樣的呢?你會發現,setValue()
其實最後就是經過調用了dispatchingValue()
方法。而關於postValue()
在子線程更新數據的相關代碼,這裏就不作介紹了,其實你大能夠想出來,就是使用的Handler
。
LiveData
中的代碼很簡潔,400多行的代碼,看起來也並不費勁,下面咱們來分析下整個流程:
LiveData
對象,爲它建立觀察者Observer
Observer
時綁定Fragment
生命週期LifecycleBoundObserver
生命週期變化時,dispatchValue
下發更新LiveData
中的值LiveData
主動setValue
時,會主動dispatchValue
,而且會considerNotify
激活observer
咱們在開發中常常會遇到這種場景,有時咱們須要根據另一個LiveData
實例返不一樣的LiveData
實例,而後在分發給Observer
,Lifecycle
包提供了Transformations
類,能夠幫助咱們實現這樣的場景:
經過**Transformations.map()**使用一個函數來轉換存儲在 LiveData
對象中的值,並向下傳遞轉換後的值:
LiveDataViewModel
class LiveDataViewModel : ViewModel() {
val data = listOf(User(0,"Hankkin"), User(1,"Tony"),User(2,"Bob"),User(3,"Lucy"))
val id = MutableLiveData<Int>()
//map轉換返回User實體
val bean: LiveData<User> = Transformations.map(id, Function {
return@Function findUserById(id.value!!)
})
//根據id查找User
private fun findUserById(id: Int): User? {
return data.find { it.id == id }
}
}
複製代碼
LiveDataFragment
//改變ViewModel中idLiveData中的值
btn_observer_map.setOnClickListener {
mId++
viewModel.id.postValue(mId)
}
//當idLiveData變化後,UserBean也會改變且更新Textview的文本
viewModel.bean.observe(
this,
Observer { tv_livedata_map.text = if (it == null) "未查找到User" else "爲你查找到的User爲:${it.name}" })
複製代碼
@MainThread
public static <X, Y> LiveData<Y> map( @NonNull LiveData<X> source, @NonNull final Function<X, Y> mapFunction) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();
result.addSource(source, new Observer<X>() {
@Override
public void onChanged(@Nullable X x) {
result.setValue(mapFunction.apply(x));
}
});
return result;
}
複製代碼
咱們能夠看到map
的源碼是經過MediatorLiveData
中的addSource()
方法來實現的,第一個參數爲咱們須要改變的LiveData
值,也就是咱們上面例子中的userid
,第二個參數則是咱們傳過來的Fuction
經過高階函數,將值set到LiveData上。
下面咱們看下addSource()
方法:
@MainThread
public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
Source<S> e = new Source<>(source, onChanged);
Source<?> existing = mSources.putIfAbsent(source, e);
if (existing != null && existing.mObserver != onChanged) {
throw new IllegalArgumentException(
"This source was already added with the different observer");
}
if (existing != null) {
return;
}
if (hasActiveObservers()) {
e.plug();
}
}
複製代碼
這裏把咱們的LiveData和Observer封裝成了Source對象,而且這個對象,不能重複添加,具體代碼可查看Source
:
private static class Source<V> implements Observer<V> {
final LiveData<V> mLiveData;
final Observer<? super V> mObserver;
int mVersion = START_VERSION;
Source(LiveData<V> liveData, final Observer<? super V> observer) {
mLiveData = liveData;
mObserver = observer;
}
void plug() {
mLiveData.observeForever(this);
}
void unplug() {
mLiveData.removeObserver(this);
}
@Override
public void onChanged(@Nullable V v) {
if (mVersion != mLiveData.getVersion()) {
mVersion = mLiveData.getVersion();
mObserver.onChanged(v);
}
}
}
複製代碼
首先Source是一個觀察者,能夠看到,咱們外部使用的Observer會以Source的成員變量的形式,添加到傳入的LiveData中。值得注意的是,這裏使用了mLiveData.observeForever(this);
。
從observeForever()
用法能夠看到,咱們並無傳遞LifecycleOwner
,所以它並不具有生命感知能力。從註釋中也可見一斑:This means that the given observer will receive all events and will never be automatically removed.
map()的原理就是基於MediatorLiveData,MediatorLiveData內部會將傳遞進來的LiveData和Observer封裝成內部類,而後放在內部維護的一個Map中。而且自動幫咱們完成
observeForever
()和removeObserver()
。
LiveData
基於觀察者模式實現,而且和LifecycleOwner
進行綁定,而LifecycleOwner
又被Fragment
和Activity實現,因此它能夠感知生命週期;在當前的LifecycleOwner不處於活動狀態(例如onPasue()
、onStop()
)時,LiveData是不會回調observe()
的,由於沒有意義.LiveData
只會在LifecycleOwner
處於Active
的狀態下通知數據改變,果數據改變發生在非 active 狀態,數據會變化,可是不發送通知,等 owner
回到 active 的狀態下,再發送通知;LiveData
在DESTROYED時會移除Observer
,取消訂閱,不會出現內存泄漏postValue
在異步線程,setValue
在主線程LiveData
沒有被observe()
,那麼此時你調用這個LiveData的postValue(...)/value=...,是沒有任何做用固然官方推薦咱們LiveData
配合ViewModel
一塊兒使用,由於LiveData
通常都出如今ViewModel
中,因此咱們下篇文章會繼續分析ViewModel
.