本文为《Android Architecture Components学习笔记》的一部分
水平有限,如有不当之处请不吝赐教
可参考:
https://developer.android.google.cn/topic/libraries/architecture/livedata#use_livedata_with_room
使用LiveData的优点:
-
确保UI与数据更新一致
LiveData遵循观察者模式。当生命周期状态改变时,LiveData作为被观察者会通知Observer对象中的UI执行更新。这样可以方便、集中的更新UI,而不需要逐个实现UI更新事件。 -
防止内存泄漏
当关联到Lifecycle对象的生命周期处于销毁状态时,被绑定到观察者的对象可自行清理。 -
Activity停止后不会导致崩溃
如果观察者生命周期处于非活动状态,例如在回退栈中的Activity,则它不会收到任何关于LiveData的事件。 -
不需要更多的手动生处理命周期
生命周期状态由LiveData自动管理,无需手动实现。 -
自动获取最新数据
如果生命周期变为活动状态,它将收到最新数据。例如,后台活动在返回到前台后立即收到最新数据。 -
保持数据一致性
重新创建Activity或Fragment(如设备旋转)时,它会立即收到最新的可用数据。 -
共享资源
可以用LiveData单例模式包装系统服务,从而可以在app中共享。LiveData对象仅需连接到系统服务,其他需要该资源的观察者都可获得数据。
我觉学习LiveData会有三个收获:观察者模式、自动更新、生命周期。
观察者模式
关于观察者模式也许并不陌生。这里我们来看看LiveData的观察者模式是怎么实现的。
为了方便理解,我模拟了一套LiveData类,分别是:MyObserver、MyLiveData、MyMediatorLiveData、MyMutableLiveData
。它们都是系统类名字前加了My,结构、成员名都是按照系统类的定义。
模拟的Observer类,名字为MyObserver:
public interface MyObserver<T> {
void onChanged(@Nullable T t);
}
注意:LiveData
使用的Observer是android.arch.lifecycle
包的。
模拟的LiveData类,名字叫MyLiveData:
//包含了LIveData核心的成员。名称都与LiveData保持一致,数据类型也基本相同。
public class MyLiveData<T> {
private static final Object NOT_SET = new Object();
//自己的数据
private volatile Object mData = NOT_SET;
//放观察者的map
private SafeIterableMap<MyObserver<T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
//通知变更,也就是执行观察者的onChanged()方法
private void considerNotify(ObserverWrapper observer) {
observer.mObserver.onChanged((T) mData);
}
//调度值变更,当LiveData数据发生改变时,通过此方法遍历观察者以执行其onChanged()方法
private void dispatchingValue() {
for (@SuppressLint("RestrictedApi")
Iterator<Map.Entry<MyObserver<T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
}
}
//注册观察者
public void observe(@NonNull MyObserver<T> observer) {
ObserverWrapper wrapper = new ObserverWrapper(observer);
//将观察者放入mObservers
mObservers.putIfAbsent(observer, wrapper);
}
public void removeObserver(@NonNull final MyObserver<T> observer) {
mObservers.remove(observer); }
//改变数据
public void setValue(T value) {
mData = value