1、什么是LiveData
基于觀察者的消息訂閱/分發組件,依靠Lifecycles確保LiveData的數據僅分發給處于活躍狀態的觀察者。
2、LiveData的使用
- 導入依賴
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
LiveData在實戰中一般都是作為網絡請求的數據分發,LiveData本身就是一個觀察者模式,在實戰中,網絡請求的時候,LiveData便將數據分發出去。
MutableLiveData繼承了LiveData,一般都用MutableLiveData來做數據分發使用。還有一種MediatorLiveData也繼承了LiveData,后面會講到。
- MutableLiveData使用
class MainActivity : AppCompatActivity() {
var liveData1: MutableLiveData<Int> = MutableLiveData()
var liveData2: MutableLiveData<String> = MutableLiveData()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 注冊觀察者
startObserver()
// 數據發生改變
liveData1.postValue(1000)
liveData2.postValue("33333")
}
private fun startObserver() {
liveData1.observe(this, Observer {
Log.i("liveData1",it.toString())
})
liveData2.observe(this, Observer {
Log.i("liveData2",it.toString())
})
}
}
結果:
10-17 05:52:45.645 4197-4197/com.mg.axechen.testdemo I/liveData1: 1000
10-17 05:52:45.645 4197-4197/com.mg.axechen.testdemo I/liveData2: 33333
- MediatorLiveData
MediatorLiveData可以通過addSource
將所有的MutableLiveData統一觀察,當然他自己也是繼承了LiveData,也可以被其他的Observer觀察。
class MainActivity : AppCompatActivity() {
var liveData1: MutableLiveData<Int> = MutableLiveData()
var liveData2: MutableLiveData<String> = MutableLiveData()
var mediatorLiveData: MediatorLiveData<Any> = MediatorLiveData()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mediatorLiveData.addSource(liveData1,dataObserver2)
mediatorLiveData.addSource(liveData2,dataObserver)
mediatorLiveData.observe(this, Observer {
Log.i("liveData5",it.toString())
})
liveData1.value = 1000
liveData2.value = "axeChen"
mediatorLiveData.postValue("xxxx")
}
private var dataObserver2 = object :Observer<Int>{
override fun onChanged(t: Int?) {
Log.i("liveData4",t.toString())
}
}
private var dataObserver =object :Observer<Any> {
override fun onChanged(t: Any?) {
Log.i("liveData3",t.toString())
}
}
}
輸出結果:
10-17 06:02:21.624 4713-4713/com.mg.axechen.testdemo I/liveData4: 1000
10-17 06:02:21.624 4713-4713/com.mg.axechen.testdemo I/liveData3: axeChen
10-17 06:02:21.637 4713-4713/com.mg.axechen.testdemo I/liveData5: xxxx
3、LiveData源碼解析
3.1、LiveData的關鍵類
LiveData
public abstract class LiveData<T> {}
類聲明可以看出這個是一個抽象類,它封裝了訂閱和取消訂閱的方法:
// 訂閱Observer的方法
public void observe(@NonNull LifecycleOwner owner,
@NonNull Observer<? super T> observer) {}
public void observeForever(@NonNull Observer<? super T> observer) {}
// 取消訂閱Observer的方法
public void removeObserver(@NonNull final Observer<? super T> observer) {}
public void removeObservers(@NonNull final LifecycleOwner owner) {}
封裝了Observerapper的子類LifecycleBoundObserver和AlwaysActiveObserver,關于Observerapper這個類,只要知道這個是用于分發數據的類,具體如何分發下面會分析到。
class LifecycleBoundObserver extends
ObserverWrapper implements LifecycleEventObserver {}
private class AlwaysActiveObserver extends ObserverWrapper {}
LifecycleBoundObserver
生命周期安全的Observer。
class LifecycleBoundObserver extends
ObserverWrapper implements LifecycleEventObserver {}
AlwaysActiveObserver
非生命周期的Observer。
private class AlwaysActiveObserver extends ObserverWrapper {}
3.2、關鍵方法
兩種訂閱方式
上面提到了生命周期安全的概念,最大的區別就是在分發數據的時候是否考慮到了生命周期。考慮和非考慮生命周期安全的方式訂閱的方式也不一樣。
LiveData中observer方法是考慮生命周期安全的訂閱方式。
observer考慮生命周期安全的方式訂閱
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 1、判斷是否在主線程中
assertMainThread("observe");
// 2、判斷當前宿主狀態是不是Destory,假如是Destory則直接return
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// 3、封裝成LifecycleBoundObserver ,
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 4、判斷是否已經存在了Observer
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
// 5、假日已經存在了Observer則拋出異常
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
// 6、訂閱觀察者
owner.getLifecycle().addObserver(wrapper);
}
看下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() {
// 這里用了狀態枚舉的比較方法,去看isAtLeast方法就會明白,
// 只有當狀態為STARTED或者RESUMED算為活躍狀態,返回true
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
// 1、獲取當前宿主的生命周期狀態
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
// 2、判斷狀態是不是Destory
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
// 3、while阻塞線程
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);
}
}
activeStateChanged,中傳入是不是宿主是不是活躍的狀態。如果是活躍狀態則調用dispatchingValue。
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);
}
}
不考慮生命周期安全的observerForver
observerForver和observer最大的區別就是沒有傳入LifecycleOwner,不會考慮生命周期的變化。只要數據發生變化時就會進行數據回調。
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
// 1、判斷是不是主線程
assertMainThread("observeForever");
// 2、封裝成AlwaysActiveObserver
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
// 3、判斷是不是已經存在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;
}
// 4、回調數據
wrapper.activeStateChanged(true);
}
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
// 當initiator 不為空就將這發送給自己,這個在Observer注冊的時候會調用
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
// 遍歷所有的Observer并分發數據
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
AlwaysActiveObserver
最終分發數據的方法是considerNotify
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
// 永久返回True
return true;
}
}
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;
}
// 同步Version
observer.mLastVersion = mVersion;
// 分發數據
observer.mObserver.onChanged((T) mData);
}
從AlwaysActiveObserver可以看到,shouldBeActive()永久為true。只要有數據就會立即回調。
代碼中已經非常明白了,先判斷是不是處于活躍狀態。然后再分發數據。
3.3、移除訂閱
這個就是將訂閱移除掉
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
assertMainThread("removeObserver");
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
return;
}
removed.detachObserver();
removed.activeStateChanged(false);
}
@MainThread
public void removeObservers(@NonNull final LifecycleOwner owner) {
assertMainThread("removeObservers");
for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
if (entry.getValue().isAttachedTo(owner)) {
removeObserver(entry.getKey());
}
}
}
3.4、PostValue()、setValue()
從一開始的例子可以知道,如果調用了這兩個方法,liveData.observer{}就可以觀察到值的變化,從而獲取到新的值。這兩個方法是更新LiveData值的方法。
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
這兩個的區別:
- 1、setValue只能在主線程中調用。
- 2、postValue能在子線程中調用,具有同步鎖的功能。
- 3、postValue多次調用只有最后一個值才有效。
4、總結
LiveData使用的時候會根據宿主是不是活躍去分發數據,減少了一些因為Activity,Fragment不可見而處理數據,浪費了資源的情況,使用時盡量使用安全的訂閱方式和postValue方法。