本篇文章主要讲解LiveData工做的原理,若是还不知道LiveData如何用的话,请参考官方文档。 LiveData的讲解涉及到了Lifecycle的知识,若是你还不了解LifeCycle,请参考文档LifeCycle介绍。android
LiveData是一个数据持有类,它能够经过添加观察者被其余组件观察其变动。不一样于普通的观察者,它最重要的特性就是听从应用程序的生命周期,如在Activity中若是数据更新了但Activity已是destroy状态,LivaeData就不会通知Activity(observer)。固然。LiveData的优势还有不少,如不会形成内存泄漏等。
数据库
LiveData一般会配合ViewModel来使用,ViewModel负责触发数据的更新,更新会通知到LiveData,而后LiveData再通知活跃状态的观察者。bash
下面直接看代码:网络
public class UserProfileViewModel extends ViewModel {
private String userId;
private MutableLiveData<User> user;
private UserRepository userRepo;
public void init(String userId) {
this.userId = userId;
userRepo = new UserRepository();
user = userRepo.getUser(userId);
}
public void refresh(String userId) {
user = userRepo.getUser(userId);
}
public MutableLiveData<User> getUser() {
return user;
}
}
复制代码
上面UserProfileViewModel内部持有 UserRepository 中 MutableLiveData的引用,而且提供了获取 MutableLiveData 的方法 getUser(),UserRepository 负责从网络或数据库中获取数据并封装成 MutableLiveData 而后提供给 ViewModel。
app
咱们在 UserProfileFragment 中为 MutableLiveData 注册观察者,以下:ide
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String userId = getArguments().getString(UID_KEY);
viewModel = ViewModelProviders.of(this).get(UserProfileViewModel.class);
viewModel.init(userId);
//标注1
viewModel.getUser().observe(UserProfileFragment.this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
if (user != null) {
tvUser.setText(user.toString());
}
}
});
}
复制代码
看标注1处,viewModel.getUser()获取到 MutableLiveData 也就是咱们的 LiveData,而后调用 LiveData的observer方法,并把UserProfileFragment做为参数传递进去。observer() 方法就是咱们分析的入口了,接下来咱们看LiveData的observer()方法都作了什么:post
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
//标注1
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//标注2
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);
}
复制代码
能够看到,UserProfileFragment 是做为 LifeCycleOwner 参数传进来的,若是你的support包版本大于等于26.1.0,support包中的 Fragment 会默认继承自 LifecycleOwner,而 LifecycleOwner 可获取到该组件的 LifeCycle,也就知道了 UserProfileFragment 组件的生命周期(在这里默认你们已经了解过LifeCycle了)。
看标注1处,若是咱们的 UserProfileFragment 组件已是destroy状态的话,将直接返回,不会被加入观察者行列。若是不是destroy状态,就到标注2处,新建一个 LifecycleBoundObserver 将咱们的 LifecycleOwner 和 observer保存起来,而后调用 mObservers.putIfAbsent(observer, wrapper) 将observer和wrapper分别做为key和value存入Map中,putIfAbsent()方法会判断若是 value 已经可以存在,就返回,不然返回null。 若是返回existing为null,说明之前没有添加过这个观察者,就将 LifecycleBoundObserver 做为 owner 生命周期的观察者,也就是做为 UserProfileFragment 生命周期的观察者。
咱们看下LifecycleBoundObserver 源码:ui
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@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);
}
}
复制代码
代码并很少,LifecycleBoundObserver 继承自 ObserverWrapper 并实现了 GenericLifecycleObserver接口,而 GenericLifecycleObserver 接口又继承自 LifecycleObserver 接口,那么根据 Lifecycle 的特性,实现了LifecycleObserver接口而且加入 LifecycleOwner 的观察者里就能够感知或主动获取 LifecycleOwner 的状态。
this
好了,看完了观察者,那么咱们的LiveData何时会通知观察者呢?不用想,确定是数据更新的时候,而数据的更新是咱们代码本身控制的,如请求网络返回User信息后,咱们会主动将User放入MutableLiveData中,这里我在UserRepository中直接模拟网络请求以下:spa
public class UserRepository {
final MutableLiveData<User> data = new MutableLiveData<>();
public MutableLiveData<User> getUser(final String userId) {
if ("xiasm".equals(userId)) {
data.setValue(new User(userId, "夏胜明"));
} else if ("123456".equals(userId)) {
data.setValue(new User(userId, "哈哈哈"));
} else {
data.setValue(new User(userId, "unknow"));
}
return data;
}
}
复制代码
当调用getUser()方法的时候,咱们调用MutableLiveData的setValue()方法将数据放入LiveData中,这里MutableLiveData实际上就是继承自LiveData,没有什么特别:
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
复制代码
setValue()在放入User的时候必须在主线程,不然会报错,而postValue则没有这个检查,而是会把数据传入到主线程。咱们直接看setValue()方法:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
复制代码
首先调用assertMainThread()检查是否在主线程,接着将要更新的数据赋给mData,而后调用 dispatchingValue()方法并传入null,将数据分发给各个观察者,如咱们的 UserProfileFragment。看 dispatchingValue()方法实现:
private void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
//标注1
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//标注2
for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
复制代码
从标注1能够看出,dispatchingValue()参数传null和不传null的区别就是若是传null将会通知全部的观察者,反之仅仅通知传入的观察者。咱们直接看标注2,通知全部的观察者经过遍历 mObservers ,将全部的 ObserverWrapper 拿到,实际上就是咱们上面提到的 LifecycleBoundObserver,通知观察者调用considerNotify()方法,这个方法就是通知的具体实现了。
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);
}
复制代码
若是观察者不是活跃状态,将不会通知此观察者,看最后一行,observer.mObserver.onChanged((T) mData),observer.mObserver就是咱们调用LiveData的observer()方法传入的 Observer,而后调用 Observer 的 onChanged((T) mData)方法,将保存的数据mData传入,也就实现了更新。在看下咱们实现的Observer:
viewModel.getUser().observe(UserProfileFragment.this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
if (user != null) {
tvUser.setText(user.toString());
}
}
});
复制代码
若是哪一个控件要根据user的变动而及时更新,就在onChanged()方法里处理就能够了。到这里,LiveData已经可以分析完了,其实LiveData的实现仍是要依赖于Lifecycle。