本系列博客基于androidx-2.2.0版本
【JetPack系列】——Lifecycle源碼分析
【JetPack系列】——LiveData源碼解析
【JetPack系列】——ViewModel源碼解析
前言
前一篇博客分析了LiveCycle的源碼分析,有了LiveCycle的了解,對(duì)于我們LiveData就非常容易了。首先我們先了解下LiveData是什么,同樣這里放上Google的官方介紹鏈接
LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.
從介紹可以看到,LiveData同樣也是觀察者模式的應(yīng)用,只不過用于通知數(shù)據(jù)更新的,而相較于Rxjava和EventBus這類消息的事件總線的框架不同的是,LiveData正如其名字那樣具有Live感知生命周期的能力,它只會(huì)在觀察者處于active的狀態(tài)下才會(huì)通知數(shù)據(jù)改變。
源碼分析
class NameViewModel : ViewModel() {
// Create a LiveData with a String
val currentName: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
// Rest of the ViewModel...
}
class NameActivity : AppCompatActivity() {
// Use the 'by viewModels()' Kotlin property delegate
// from the activity-ktx artifact
private val model: NameViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Other code to setup the activity...
// Create the observer which updates the UI.
val nameObserver = Observer<String> { newName ->
// Update the UI, in this case, a TextView.
nameTextView.text = newName
}
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
model.currentName.observe(this, nameObserver)
}
}
看下官方的Demo介紹,可以看到使用很簡單,我們首先在ViewModel中構(gòu)造一個(gè)LiveData,然后在Activity中使用即可。以為LiveData的構(gòu)造函數(shù)這里沒有什么特殊處理,所以我們這里就看下觀察的地方。
觀察LiveData
@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);
}
可以看到?jīng)]有什么特別復(fù)雜的處理,如果看過上一篇博客的話,可以看到這里應(yīng)該會(huì)很熟悉,因?yàn)樘幚淼倪壿嫼芟嗨啤?br>
首先看到?jīng)]有LiveData對(duì)于生命周期的處理這里已經(jīng)展現(xiàn)出來了,首先方法的入?yún)⒂幸粋€(gè)LivecycleOwner,也就是生命周期的感知者,對(duì)應(yīng)到Activity和Fragment。如果是在Destroy的時(shí)候,那么這里首先就會(huì)攔截,不允許注冊LiveData了。
后面這里使用了一個(gè)包裝類LifecycleBoundObserver,來包裝我們的LivecycleOwner和Observer
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull 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);
}
}
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
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);
}
}
}
代碼沒有特別復(fù)雜,這里先不展開介紹,后面具體使用的時(shí)候再展開介紹。大體瀏覽下來的第一感覺就是這個(gè)類的作用就是將LifecycleOwner和Observer兩個(gè)類包裝起來,并且加上了生命周期的判斷處理。
接下來就比較簡單了,首先判斷這個(gè)觀察者有沒有被加入過,如果加入過這里就拋異常,然后加入LifecycleOwner觀察。所以觀察的地方這里就分析完了,沒有太特殊的邏輯。
LiveData更新
public class MutableLiveData<T> extends LiveData<T> {
/**
* Creates a MutableLiveData initialized with the given {@code value}.
*
* @param value initial value
*/
public MutableLiveData(T value) {
super(value);
}
/**
* Creates a MutableLiveData with no value assigned to it.
*/
public MutableLiveData() {
super();
}
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
因?yàn)檫@里是介紹原理,所以就看一下我們經(jīng)常使用的MutableLiveData??梢钥吹接袃蓚€(gè)方法,一個(gè)是setValue一個(gè)是postValue??吹竭@個(gè)名字我們應(yīng)該會(huì)非常敏感,因?yàn)橐粋€(gè)是post和我們使用Handler里使用的post很相似。
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
可以看到這里其實(shí)最后使用的還是setValue,只不過這里使用Handler.post到了主線程(沒有放具體代碼,但是比較簡單),但是這里有一個(gè)點(diǎn)需要注意下,因?yàn)檫@里可以看到因?yàn)槭怯胮ost到主線程,如果我們子線程連續(xù)兩次執(zhí)行postValue,也就是在runnable還沒有執(zhí)行的時(shí)候,我們多次修改mPendingData的值,那么其實(shí)最后可能最終得到的是最后一次的值,因?yàn)椴⒉皇敲恳淮握{(diào)用postValue都會(huì)執(zhí)行Handler.post操作,這個(gè)需要我們注意下。
所以剩下的我們就來看下setValue的實(shí)現(xiàn)。
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
沒有太復(fù)雜的邏輯,這里有個(gè)版本號(hào)的邏輯,每次設(shè)置value的時(shí)候都會(huì)增加一個(gè)版本號(hào),核心邏輯在dispatchingValue
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;
}
其次這里可以看到傳入的參數(shù)是否為null也是有差異的,但最終執(zhí)行的都是considerNotify方法,從代碼可以看出來,如果傳入的不為null,則只是單純刷新一個(gè)觀察者,如果傳入的為null,則遍歷所有的觀察者進(jìn)行刷新。那么我們來看下有哪些地方調(diào)用了這個(gè)方法。

可以看到剛好有兩處,一個(gè)傳入的是this,一個(gè)傳入的是null對(duì)象。
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
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);
}
}
setValue這里就不說了,activeStateChange這里可以看下,從方法的名字上也很好理解,就是在狀態(tài)變成活躍的時(shí)候,會(huì)調(diào)用,并且傳入this對(duì)象,僅刷新一個(gè)觀察者,那么我們來看下調(diào)用這個(gè)方法的地方,驗(yàn)證一下我們的想法。
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
可以看到回到我們第一篇博客分析的地方,我們的觀察者在接受狀態(tài)回調(diào)的通知的時(shí)候,會(huì)首先看下當(dāng)前的狀態(tài)是不是Destroy,如果是的話則會(huì)執(zhí)行移出觀察者,所有這里我們可以可以得出一個(gè)結(jié)論:LiveData在Destroy的時(shí)候會(huì)移除自身,并且不會(huì)收到回調(diào),所以我們也不用擔(dān)心內(nèi)存泄漏和空指針的情況發(fā)生。
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;
observer.mObserver.onChanged((T) mData);
}
首先可以看到這里又加了一層判斷,如果當(dāng)前觀察者的狀態(tài)不是活躍的,那么就不會(huì)執(zhí)行通知,而這個(gè)mActive對(duì)象在什么地方賦值呢。沒錯(cuò),又回到我們剛才分析的activeStateChanged方法,那么可以看到mActive的對(duì)象的值是由shouldBeActive()方法決定的。
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
所以可以看到,對(duì)于活躍的定義就我們的觀察者的狀態(tài)必須是大于等于onStart生命周期。
繼續(xù)看下面的邏輯,其實(shí)這塊邏輯我一開始是有點(diǎn)困惑的,而且看了網(wǎng)上很多關(guān)于LiveData的源碼分析博客,都對(duì)這里沒有提及,或者一掠而過。
// 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;
}
其實(shí)可以看到這里注釋也很多,這里我困惑的地方是這樣的,剛才前面已經(jīng)做了mActive的狀態(tài)判斷,那么為什么這里又要做一個(gè)關(guān)于active狀態(tài)判斷呢,會(huì)不會(huì)有些多余?
那么這里我們就看一下二者的區(qū)別,一個(gè)是對(duì)于mActive的判斷,一個(gè)是對(duì)Onwer的生命周期的判斷,能夠走到這個(gè)if條件里面的case,說明當(dāng)前觀察者是活躍狀態(tài),但是被觀察者不是活躍狀態(tài)。那么這里我們就可以想到一個(gè)case了。
假如我們的
Activity以及是Stop狀態(tài),我們此時(shí)的注冊的觀察者有A,B,C(LiveData),其中C是LiveData的的綁定的觀察者,如果我們在A的生命周期回調(diào)的地方,調(diào)用C的LiveData的setValue方法,那么就會(huì)出現(xiàn)我們C的狀態(tài)還沒有接收到stop的狀態(tài),需要執(zhí)行setValue方法,但是這時(shí)候其實(shí)Activity其實(shí)已經(jīng)是stop狀態(tài)了,那么就和LiveData的初心違背了。
所以這里這個(gè)判斷就是處理這種特殊case的,也就是嵌套通知或者說是重入,其實(shí)看過其第一篇博客
的應(yīng)該也會(huì)發(fā)現(xiàn)有關(guān)于重入的概念,我們會(huì)發(fā)現(xiàn)Google在處理觀察者模式的時(shí)候,對(duì)于重入的處理其實(shí)是值得我們學(xué)習(xí)的,往往我們自己設(shè)計(jì)的觀察者模式是忽略這種情況的。
后面這里有個(gè)關(guān)于版本的判斷,其實(shí)一開始我是忽略版本的這塊邏輯的,因?yàn)槲覜]發(fā)現(xiàn)這塊的太具體的作用。但是最新又想了想這塊還是需要特殊說明的??催^前面的分析我們應(yīng)該會(huì)發(fā)現(xiàn)LiveData其實(shí)是有一個(gè)特性的,那就是粘性事件,比如這里舉一個(gè)例子。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//還沒監(jiān)聽,先設(shè)置值
liveDataViewModel.getLiveDate().setValue(10);
//再監(jiān)聽
liveDataViewModel.getLiveDate().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
Log.i("LiveData-Value", "" + integer);
}
});
}
這里我們先調(diào)用了LiveData.setValue方法,設(shè)置value為10,然后再注冊一個(gè)觀察者,那么這個(gè)通知會(huì)收到嗎?會(huì)在什么時(shí)候收到呢?
這里先給下結(jié)論,會(huì)收到通知,會(huì)在onStart回調(diào)收到之后收到通知
1.其實(shí)具體的原來上面都已經(jīng)分析到了,只不過沒有結(jié)合具體的例子分析,這里就簡單分析下。
首先我們調(diào)用setValue的時(shí)候,會(huì)將LiveData內(nèi)部的value設(shè)置為10,其次會(huì)將version++,也就是1,然后本來應(yīng)該通知觀察LiveData的觀察者刷新數(shù)據(jù)的,因?yàn)榇藭r(shí)沒有觀察者,并且就算有,此時(shí)也不是active狀態(tài),所以也不會(huì)通知。
2.然后我們調(diào)用Observer方法,注冊了一個(gè)LiveData觀察者,按照第第一篇博客的分析,我們會(huì)回溯生命周期,但是這里其實(shí)是在onCreate注冊的,和Owner保持同步,所以也不會(huì)執(zhí)行生命周期的同步,也就是單純的注冊,也就是說我們在注冊了觀察者后不會(huì)立即收到回調(diào)。
3.接著我們Activity在收到onStart生命周期回調(diào)后會(huì)通知觀察者,這時(shí)候就會(huì)通知我們剛才注冊的觀察者了,這時(shí)候由于觀察者的狀態(tài)會(huì)從不活躍變成活躍。
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
所以就會(huì)執(zhí)行到我們剛才分析的地方,這里最后就會(huì)執(zhí)行我們剛才提到的版本判斷,因?yàn)槲覀冏缘接^察者的version初始值是-1,而當(dāng)前LiveData的version是1,所以就會(huì)執(zhí)行onChange方法,執(zhí)行通知刷新。
這樣整個(gè)流程就串起來了。
總結(jié)
LivaData我們可以看到是一個(gè)很輕量級(jí)的數(shù)據(jù)驅(qū)動(dòng)框架,并且結(jié)合Lifecycle,使得其有了感知生命周期的能力,所以我們可以得出LiveData有以下特性:
- 感知生命周期
- 不會(huì)有內(nèi)存泄漏,自動(dòng)在Destroy的時(shí)候解綁
- 支持粘性事件
- 支持嵌套事件
- 輕量級(jí)
- 支持重入
- 不支持跨頁面使用(個(gè)人不傾向于這樣使用)
綜上,可以看出LiveData還是一個(gè)很優(yōu)秀 的框架的,大家快去使用吧~