一、优点:
-
LiveData 可以很大程度上避免内存泄漏;
-
更好的将View层与Model层分离。
二、常用方法
LiveData是基于观察者机制实现的,LiveData是被观察者,Observer是观察者,
当LiveData有数据变化时会通知他的观察者去更新数据。
常用方法如下:
-
setValue
-
postValue
-
observe
-
observeForever
三、setValue
setValue 跟 postValue 都是用来修改LiveData值的。
「setValue 源码」
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
Tips:
-
MainThread表示setValue只能在主线程中调用,
-
assertMainThread("setValue")判断当前调用是否在主线程中,如果不是会抛异常。
-
mVersion++ 用于记录LiveData是否有更新,每更新一次,mVersion都加一;
-
dispatchingValue(null) 用于通知观察者更新数据
// 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;
}
}
Tips
dispatchingValue(@Nullbale ObserverWrapper initiator)
传入的参数是观察者,如果非空,则只通知这个观察者进行数据更新,否则会遍历该LiveData下所有的观察者,并一一通知更新。
上述代码中真正通知观察者去进行数据更新的是considerNotify()方法
/**
*1、「observer.mActive」 判断观察者是否处于活跃状态
*2、「observer.shouldBeActivie」 判断所在页面是否处于活跃状态(比如观察者所在页面已进入 onDestroy函数,则页面就是非活跃状态),如果页面不处于活跃状态,则需要把观察者自身状态修改为 非活跃状态
*3、活跃状态下,观察者自身的「mLastVersion」与LiveData的「mVersion」对比,若mLastVersion >= mVersion 表示没有更新
*4、最后,有更新情况下,观察者修改自身mLastVersion,并调用onChanged做数据更新
*/
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);
}
四、postValue
「postValue」与「setValue」区别是:
setValue只能在主线程中调用,而postValue可以在任意线程中调用。
同时,postValue内部最终还是通过setValue来实现数据更新的。
还有一点,多次调用postValue,只有最后一次调用时传入的值有效。
postValue源码如下
static final Object NOT_SET = new Object();
volatile Object mPendingData = NOT_SET;
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);
}
};
observer.shouldBeActive()
LiveData中的两种观察者
* LifecycleBoundObserver
LifecycleBoundObserver中的shouldBeActive方法,会判断页面至少要处于started状态才认为是处于活跃状态,
正因为shouldBeActivie方法的实现,才使得LiveData具有可以避免内存泄漏的能力。
LifecycleBoundObserver源码
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
......
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
......
}
public enum State {
// onDestroy()
DESTROYED,
INITIALIZED,
// 介于 onCreate() -- onStop() 之间
CREATED,
// 介于 onStart() -- onPause() 之间
STARTED,
// onResume()
RESUMED;
public boolean isAtLeast(@NonNull State state) {
}
}