LiveData是一个可观察的数据存储器。它可以通过观察者Observer与LifecycleOwner配对来感知数据依附组件的生命周期状态,只会把更新通知发给活跃的观察者,所谓活跃就是观察者处于STARTED或者RESUMED状态而没有DESTROYED。
既然是数据存储器,他是如何更新数据呢
LiveData有postValue()和setValue()方法去更新数据。postValue(T value)可以在任意线程使用,setValue(T value)只能在主线程更新数据。
postValue(T value)源码:
protected void postValue(T value) {
//定义一个boolean值
boolean postTask;
//可以在任意线程 所以要加锁
synchronized (mDataLock) {
//NOT_SET全局的一个空对象 mPendingData初始值就是NOT_SET 从此处代码的理解我们
//要结合下面mPostValueRunnable去理解 每一次主线程更新数据之后重新初始
//mPendingData的值 postTask才会为true 才可以下一次更新
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
//去主线程更新数据
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
通过postValue(T value)源码我们可以知道他只是在多线程调用时候加了个锁,然后最终还是通过setValue(T value)去分发数据。
setValue(T value)源码:
@MainThread
protected void setValue(T value) {
//先判断当前线程是否为主线程,是的话数据版本+1 然后dispatching数据 是不是想到了view的
//事件分发- -
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
//为什么setValue中该方法参数会传null,这要从该方法调用的两种情况说起
//一个情况就是setValue 那就传一个null 去把数据更新到所有活跃的观察者
//另一个情况就是某一个观察者由不活跃状态到活跃状态 更新该观察者对应的被观察者
//知道了这两种情况 这里的代码就好理解了
@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;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
通过setValue(T value)的源码,我们看到LiveData在更新数据时会遍历所有注册的观察者,只有活跃的观察者才可以通知UI更新。
那LiveData又是如何感知观察者的活跃状态呢
首先我们来看LiveData的使用示例代码:
viewModel.getData().observe(this,object :Observer<List<String>> {//非lamda更直观
override fun onChanged(t: List<String>?) {
//TODO 更新UI
}
})
通过observe方法的操作:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//主线程判断
assertMainThread("observe");
//生命周期状态判断 销毁了就别费事了
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//observer和Liferecycle完美结合 LifecycleBoundObserver实现了LifecycleObserver
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);
}
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
//是否是Started以及之上的状态
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
//组件Lifecycle生命周期状态变化调用该方法 组件销毁就移除该观察者 组件起死回生就更新数
//据
@Override
public void onStateChanged(LifecycleOwner source, 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);
}
}
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) {
//成功和setValue源码汇合
dispatchingValue(this);
}
}
源码看完夸两句,LiveData的优势:
确保界面符合数据状态
LiveData 遵循观察者模式。当生命周期状态发生变化时,LiveData 会通知 Observer
对象。您可以整合代码以在这些 Observer
对象中更新界面。观察者可以在每次发生更改时更新界面,而不是在每次应用数据发生更改时更新界面。
不会发生内存泄露
泄漏?不存在的,这辈子都不可能泄漏的!
不会因 Activity 停止而导致崩溃
如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。(异步数据页面关闭的View空指针)
不再需要手动处理生命周期
界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
数据始终保持最新状态
如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
适当的配置更改
再也不用担心横竖屏组件重新装件去保存数据了。
共享资源
您可以使用单一实例模式扩展 LiveData
对象以封装系统服务,以便在应用中共享它们。LiveData
对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData
对象