LiveData 是可被观察(observable)的数据源的包装类,可以配合Lifecycle感知程序组件( Activity或者Fragment)生命周期, 只有前台活动( STARTED 或 RESUMED 状态)的组件才会收到 LiveData 数据变化的通知,LiveData 仅在数据发生更改时才发送更新,并且仅发送给注册的活跃观察者,非活跃状态观察者不会收到更改通知,避免组件销毁后发生意想不到的崩溃情况。我们经常会用LiveData共享资源,用 setValue(T)方法以从主线程更新LiveData对象。如果在 worker 线程中执行代码,则您可以改用 postValue(T)方法来更新LiveData对象。
LiveData的基本使用
//新建LiveData数据包装类
MutableLiveData<String> mLiveData = mTestViewModel.getLiveData();
//添加观察者,观察数据变化
mLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
//更新UI
}
});
//数据更新,会回调给观察者
mLiveData.setValue("更新数据");
添加观察者
通过调用LiveData的observe()方法来注册观察者,LiveData的observe()方法如下:
//参数一:owner需要实现LifecycleOwner接口,即为activity或fragment
//参数二 :observer观察者即数据变化的回调接口
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//获取组件当前的生命周期状态,如果状态为DESTROYED,那么直接return,这就保证了DESTROYED状态的组件是不允许注册的
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//将owner和observer封装数据为生命感知的观察者
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//缓存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;
}
//LiveData内部完成了Lifecycle的观察者的添加,这样LiveData就有了观察组件生命周期变化的能力。
owner.getLifecycle().addObserver(wrapper);
}
LiveData生命周期变化回调observe方法
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
...
//每次生命周期变化的时候都会回调这个方法
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
//当组件处于DESTROYED状态时,会调用removeObserver方法,来移除observer。所以当组件销毁时,注册的生命周周观察者不会再接收到通知,因为已经解绑了
removeObserver(mObserver);
return;
}
//用于判断当前传入的组件的状态是否是Active的,Active状态包括STARTED和RESUMED状态
activeStateChanged(shouldBeActive());
}
}
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
...
//当生命周期出现变化的时候会回调这个方法
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);
}
}
}
public abstract class LiveData<T> {
...
@SuppressWarnings("WeakerAccess") /* synthetic access */
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;
}
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);
}
}
LiveData通过setValue和postValue触发回调observe方法
public abstract class LiveData<T> {
...
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);
}
//主线程调用
protected void setValue(T value) {
assertMainThread("setValue");
//每次设置mVersion就会加1
mVersion++;
mData = value;
dispatchingValue(null);
}
}
网友评论