首先
LiveData
是一個抽象類亭枷,是不能直接new一個出來的砸狞,通常是使用MutableLiveData
創(chuàng)建一個livedata對象阳似。MutableLiveData僅僅只是實現(xiàn)了LiveData闷堡,沒有額外的操作隘膘。
創(chuàng)建及注冊
val liveData = MutableLiveData("333")
//注冊
liveData.observe(this,{})
liveData.observeForever { }
//源碼
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
@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);
}
observe()要求傳入一個LifecycleOwner和Observer。
- LifecycleOwner:用于判斷生命周期杠览,為的就是感知生命周期弯菊,在不同階段做出不同的反應,比如在destroy的時候會直接忽略掉這個observer踱阿。
- Observer:觀察者管钳,當數(shù)據(jù)發(fā)生變化的時候就是通過這個發(fā)送通知的
observe主要步驟:
- 創(chuàng)建LifecycleBoundObserver钦铁,LifecycleBoundObserver主要的職責是結合生命周期維護LiveData的狀態(tài)
- 將我們創(chuàng)建的LifecycleBoundObserver加入到mObservers中,mObservers是一個以Observer作為key才漆,LifecycleBoundObserver為value的SafeIterableMap牛曹,注意雖然他的名字是Safe但并不是線程安全的,這里就不展開來講了栽烂。
- 將創(chuàng)建的LifecycleBoundObserver加入到LifecycleOwner的Lifecycle中躏仇,如果LifecycleOwner的狀態(tài)發(fā)生變化,也會通知到我們的LifecycleBoundObserver中腺办。
注意這里的existing和isAttachedTo的判斷
如果這個Observer已經(jīng)存在了并且owner和舊的owner不一致焰手,就會直接拋出異常。在Activity嵌套Fragment的時候共享一個ViewModel的時候怀喉,如果你在Activity和Fragment中對同一個LiveData是通過Lambda的方式創(chuàng)建Observer的书妻,那就可能會遇到這個異常,因為你通過Lambda創(chuàng)建的對象是同一個躬拢,你可以通過object:Observer{}的方式創(chuàng)建Observer對象
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
observeForever用的是AlwaysActiveObserver躲履,和LifecycleBoundObserver一樣都是繼承的ObserverWrapper,但是AlwaysActiveObserver的shouldBeActive默認返回的是true聊闯,所以消息的通知是不受生命周期影響的工猜,也就是說無論在處于什么狀態(tài),都會收到通知菱蔬。而且在你調(diào)用observeForever的時候篷帅,LiveData的狀態(tài)就直接設置成了true(mActive = true)
//注銷
liveData.removeObserver { }
liveData.removeObservers(this)
注銷這塊沒有太多邏輯主要就兩點:
- 從map中移除Observer
- 調(diào)用被移除的Observer的detachObserver方法并且把狀態(tài)置為false(mActive = false)
更新value
postValue
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
子線程中更新數(shù)據(jù),原理就是向主線程發(fā)送一個runable拴泌,在消息處理到這個runable的時候再進行setValue操作
注意:這里有一個同步鎖synchronized魏身,鎖的對象是mDataLock,蚪腐。這里有一個postTask箭昵,只有當mPendingData == NOT_SET的時候,也就是沒有被賦值的時候才會發(fā)送我們的runable回季,否則直接就return了那么問題來了家制,為什么只能發(fā)送一次runable?泡一?颤殴??瘾杭?诅病??原因就是在handler消息處理時,在獲取到Message的時候贤笆,如果message.isInUse()==true的時候會直接拋異常(throw new IllegalStateException(msg + " This message is already in use."))蝇棉,而我們的mPostValueRunnable對象是一個全局變量,所以得等到這個runable處理完成才能發(fā)送芥永,你也會發(fā)現(xiàn)mPostValueRunnable的run方法里將mPendingData置為了NOT_SET篡殷。雖然消息只會發(fā)送一次,但是埋涧,value賦值給mPendingData這個操作是一直在發(fā)生的板辽,所以mPostValueRunnable的run方法中取到的mPendingData只有最新的那一個,因為mPendingData是被volatile修飾的棘催,所以他的變化在其他線程中是立馬可見的劲弦。結論就是連續(xù)調(diào)用postValue,在observer中只會拿到最后的那一個
seValue
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
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;
}
setValue沒什么特別的醇坝,直接賦值然后調(diào)用dispatchingValue邑跪,這個mVersion嘛就是分發(fā)的時候做校驗用的了。
setValue進行的分發(fā)是進入②里面呼猪,直接就是進入迭代器mObservers進行分發(fā)画畅,considerNotify()方法會校驗他的version、observice的mActive狀態(tài)以及observer.shouldBeActive()狀態(tài)宋距。如果是生命周期發(fā)生變化進行的分發(fā)initiator!=null轴踱,則會進入①中。
那么問題來了mDispatchingValue和mDispatchInvalidated的含義是什么谚赎?淫僻??沸版?嘁傀?我對他的理解是:
在并發(fā)的情況下兴蒸,如果在A線程中正在進行②中的迭代并且還沒結束视粮,這時候B線程調(diào)用到了dispatchingValue方法,但是這時mDispatchingValue已經(jīng)是true了(A線程把這個值改為了true)橙凳,那么會將mDispatchInvalidated變?yōu)閠rue然后return蕾殴,這樣B線程是不會進入到后面的循環(huán)迭代中的,這時的mDispatchInvalidated已經(jīng)變成了true岛啸,那么在A線程中的迭代在遇到mDispatchInvalidated==true時會退出迭代(break钓觉,中斷數(shù)據(jù)的分發(fā)),在while時因為mDispatchInvalidated == true則會重新做一遍do里面的操作坚踩,也就是重新進入②中的迭代荡灾,這樣觀察者拿到的都會是最新的數(shù)據(jù),防止出現(xiàn)重復分發(fā)或者分發(fā)錯誤的情況。那么問題又來了批幌,既然是為了解決并發(fā)那么mDispatchInvalidated和mDispatchingValue不用volatile修飾話础锐,線程能立馬感知到嗎?荧缘?皆警?
對于這個問題我也不理解以上均是個人理解,若有問題請指出哦~
ObserverWrapper
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;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
ObserverWrapper是LivaData的內(nèi)部類截粗,他其實是對observer做了一層包裝信姓,加入了version和active屬性。在activeStateChanged方法中會改變active的狀態(tài)绸罗,如果active==true就會調(diào)用dispatchingValue分發(fā)數(shù)據(jù)意推,在開發(fā)中遇到的數(shù)據(jù)倒灌問題就是因為在生命周期發(fā)生變化的時候調(diào)用了activeStateChanged(true),導致發(fā)送了數(shù)據(jù)
LifecycleBoundObserver
LifecycleBoundObserver是ObserverWrapper的實現(xiàn)類珊蟀,當我們調(diào)用liveData.observer的時候內(nèi)部為我們的observer創(chuàng)建了一個LifecycleBoundObserver左痢,并幫我們注冊在LivecyclerOwner里,當LivecyclerOwner生命周期發(fā)生變化是就會調(diào)用到LifecycleBoundObserver的onStateChanged方法
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) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
shouldBeActive是用來判斷是否可以發(fā)送通知的系洛,由此可見只有在生命周期大于等于STARTED的時候才是可用的俊性。onStateChanged是當生命周期發(fā)生變化的時候會調(diào)用,在這里不斷的去校驗Lifecycle的狀態(tài)并且調(diào)用activeStateChanged方法改變liveData的狀態(tài)描扯,直到Lifecycle的狀態(tài)穩(wěn)定