简介
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData具有生命周期感知能力,意指它遵循其他应用组件(如Activity/Fragment)的生命周期。这种感知能力可确保 LiveData仅更新处于活跃生命周期状态的应用组件观察者。
优势
- UI和实时数据保持一致
LiveData 遵循观察者模式。当数据更新后,LiveData就会通知它的所有观察者;与RxJava的方法不同的是,LiveData并不是通知所有观察者,它只会通知处于活跃状态(Activity/Fragment 处于STARTED和RESUMED 状态)的观察者。
- 不会发生内存泄漏
观察者被绑定到组件的生命周期上,当被绑定的组件销毁(destory)时,观察者会立刻自动清理自身的数据。
- 不需要手动解除观察
开发者不需要在onPause或onDestroy方法中解除对LiveData的观察,因为LiveData能感知生命周期状态变化,所以会自动管理所有这些操作。
- 解决Configuration Change问题
在屏幕发生旋转或者被回收再次启动,立刻就能收到最新的数据。
用法
LiveData 和ViewModel 搭配使用
- 创建LiveData实例,指定源数据类型
LiveData是一个数据的包装。具体的包装对象可以是任何数据,包括集合。LiveData是一个抽象类,它的最简单的实现类为MutableLiveData。
public class ExViewModel extends ViewModel {
private MutableLiveData<Integer> num;
public MutableLiveData<Integer> getNum() {
if (num == null) {
num = new MutableLiveData<>();
}
return num;
}
}
- 观察LiveData中的数据
创建Observer实例,实现onChanged()方法,用于接收源数据变化并刷新UI。
num.observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
tv_num.setText(String.valueOf(integer));
}
});
通过LiveData.observe()方法对LivaData所包装的数据进行观察。在onChanged方法就会收到我们修改之后的数据,我们就可以对UI进行更改了。
- 使用LiveData 更新数据
// 获取ViewModel 对象
ExViewModel model = new ViewModelProvider(this).get(ExViewModel.class);
// 获取LiveData 对象
MutableLiveData<Integer> num = model.getNum();
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
i++;
num.setValue(i);
}
});
通过LiveData.postValue/LiveData.setValue()方法修改数据。注意:setValue()方法必须在主线程使用,如果是在工作线程中更新LiveData,则可以使用postValue()方法。
效果:
转换LiveData 数据
如果想要在LiveData对象分发给观察者之前对其中存储的值进行更改,可以使用Transformations.map()和Transformations.switchMap()。
- Transformations.map
MutableLiveData<Integer> num=new MutableLiveData<>();
LiveData<String> info=Transformations.map(num, new Function<Integer, String>() {
@Override
public String apply(Integer input) {
return input+"次点击";
}
});
info.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.e(TAG,"--->"+s);
}
});
num.setValue(1);
// 执行结果:
ExJetPackActivity: --->1次点击
通过Transformations.map()方法对源数据Integer 类型LiveData,修改成String 类型LiveData。
- Transformations.switchMap
如果想要根据某个值 切换观察不同LiveData数据,则可以使用Transformations.switchMap()方法。
MutableLiveData<String> work=new MutableLiveData<>();
work.setValue("加班");
MutableLiveData<String> rest=new MutableLiveData<>();
rest.setValue("双休");
MutableLiveData<Boolean> conditions=new MutableLiveData<>();
conditions.setValue(true);
LiveData<String> result=Transformations.switchMap(conditions, new Function<Boolean, LiveData<String>>() {
@Override
public LiveData<String> apply(Boolean condition) {
if (condition){
return rest;
}
return work;
}
});
result.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.e(TAG,"--->"+s);
}
});
// 执行结果:
ExJetPackActivity: --->双休
work、rest 作为数据源,conditions 作为判断的条件,如果为true,返回rest;否则,返回work。
- 合并多个LiveData数据源
MediatorLiveData是LiveData 的子类,允许合并多个LiveData数据源。
MediatorLiveData<String> mediatorLiveData = new MediatorLiveData<>();
MutableLiveData<String> source1 = new MutableLiveData<>();
MutableLiveData<String> source2 = new MutableLiveData<>();
mediatorLiveData.addSource(source1, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.e(TAG,"-source1-->"+s);
mediatorLiveData.setValue(s);
}
});
mediatorLiveData.addSource(source2, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.e(TAG,"--source2->"+s);
mediatorLiveData.setValue(s);
}
});
mediatorLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.e(TAG,"--mediator->"+s);
}
});
source1.setValue("上班");
source2.setValue("休息");
执行结果:
ExJetPackActivity: -source1-->上班
ExJetPackActivity: --mediator->上班
ExJetPackActivity: --source2->休息
ExJetPackActivity: --mediator->休息
通过MediatorLiveData的addSource将两个MutableLiveData合并到一起,这样当任何一个MutableLiveData数据发生变化时,MediatorLiveData都可以感知到。
源码分析
添加观察者
通过调用LiveData的observe方法来注册观察者,接着查看LiveData的observe方法。
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
...
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//如果被观察者的当前的状态是DESTROYED,就return
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//使用LifecycleOwner、observer 组装成LifecycleBoundObserver,添加到mObservers中
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 注释1
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) {
//说明已经添加到mObservers中
return;
}
//注释2
owner.getLifecycle().addObserver(wrapper);
}
注释1处将observer和LifecycleBoundObserver存储到SafeIterableMap<Observer<? super T>, ObserverWrapper>mObservers中,putIfAbsent方法,如果传入key对应的value已经存在,就返回存在的value,不进行替换。如果不存在,就添加key和value,返回null。
如果等于null,在注释2处会将LifecycleBoundObserver添加到Lifecycle中完成注册,这样当我们调用LiveData的observe方法时,实际上是LiveData内部完成了Lifecycle的观察者的添加,这样LiveData自然也就有了观察组件生命周期变化的能力。
事件回调
LiveData添加了观察者LifecycleBoundObserver,接着看如何进行回调的:
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);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
//LifecycleOwner变成DESTROYED状态,则移除观察者
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
LifecycleBoundObserver是LiveData的内部类,是对原始Observer的包装。它的构造方法参数是LifecycleOwner类型和Observer类型的参数,把LifecycleOwner和Observer绑定在一起。
LifecycleBoundObserver继承了ObserverWrapper类,重写了shouldBeActive方法,用于判断当前传入的组件的状态是否是Active的,Active状态包括STARTED和RESUMED状态。
LifecycleBoundObserver实现了GenericLifecycleObserver接口,当组件状态发生变化时,会调用onStateChanged方法;当组件处于DESTROYED状态时,会调用removeObserver方法,来移除observer。这就是LiveData自动移除观察者的原因。
如果不是DESTROYED状态,将调用父类ObserverWrapper的activeStateChanged()方法处理 这个生命周期状态变化,shouldBeActive()的值作为参数。
接着,看下抽象类ObserverWrapper
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
...
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
//活跃状态 未发生变化时,不会处理
return;
}
mActive = newActive;
//没有活跃的观察者
boolean wasInactive = LiveData.this.mActiveCount == 0;
//mActive为true表示变为活跃
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();//活跃的观察者数量 由0变为1
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();//活跃的观察者数量 由1变为0
}
if (mActive) {
dispatchingValue(this);//观察者变为活跃,就进行数据分发
}
}
}
mActive是ObserverWrapper的属性,表示此观察者是否活跃。如果活跃状态未发生变化时,不会处理。activeStateChanged方法会根据Active状态和处于Active状态的组件的数量,会对应调用onActive方法和onInactive方法回调,这两个方法用于拓展LiveData对象。
如果 mActive为true,即观察者处于Active状态,会调用dispatchingValue方法,并将自身传进去。
// LiveData 源码
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 当前正在分发
if (mDispatchingValue) {
// 分发无效
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;//标记正在分发
do {
//分发有效
mDispatchInvalidated = false;
//observerWrapper不为空,使用considerNotify()通知真正的观察者
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//observerWrapper为空,遍历通知所有的观察者
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) {//1
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);//2
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);//3
}
considerNotify方法中做了多次的判断,注释1处,如果ObserverWrapper的mActive值不为true,就直接return。
注释2处,如果当前observer对应组件的状态不是Active,就会再次调用activeStateChanged方法,并传入false,其方法内部会再次判断是否执行onActive方法和onInactive方法回调。
注释3处,如果判断条件都满足,会调用Observer的onChanged方法,这个方法正是使用LiveData的observe方法的回调,值是LivaData的变量mData。
小结: considerNotify()方法只有出于活跃状态且数据是最新的,才会去分发数据,最后回调到onChanged方法。
数据更新
当调用MutableLiveData的observe方法后,还需要通过postValue/setValue方法来更新数据,区别在于postValue(value)用于子线程。
// LiveData 源码
static final Object NOT_SET = new Object();
volatile Object mPendingData = NOT_SET;
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
// 最终会调用setValue()方法
setValue((T) newValue);
}
};
@MainThread
protected void setValue(T value) {// 注释1
assertMainThread("setValue");
//mVersion++记录当前发送的消息的次数,用于和observer的version作对比,防止消息重复
mVersion++;
mData = value;
dispatchingValue(null);
}
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
// 抛到主线程
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
从上面的代码来看,可以发现postValue()方法实际上就是将setValue方法切换到主线程调用。setValue()方法是运行在主线程中的,其内部调用了dispatchingValue方法的参数ObserverWrapper为null情况(即遍历所有观察者进行分发回调)。无论是LiveData的observe方法还是LiveData的postValue/setValue方法都会调用dispatchingValue方法。
Transformations map 方法分析
// Transformations 类源码
@MainThread
public static <X, Y> LiveData<Y> map(
@NonNull LiveData<X> source,
@NonNull final Function<X, Y> mapFunction) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();
result.addSource(source, new Observer<X>() {
@Override
public void onChanged(@Nullable X x) {
result.setValue(mapFunction.apply(x));
}
});
return result;
}
Transformations.map方法运行在主线程,创建了MediatorLiveData,紧接着调用了它的addSource方法,传入参数是LiveData 类型的source 和 新建 Observer 类型的内部类。
// MediatorLiveData 类源码
private SafeIterableMap<LiveData<?>, Source<?>> mSources = new SafeIterableMap<>();
@MainThread
public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
Source<S> e = new Source<>(source, onChanged);
Source<?> existing = mSources.putIfAbsent(source, e);
if (existing != null && existing.mObserver != onChanged) {
throw new IllegalArgumentException(
"This source was already added with the different observer");
}
if (existing != null) {
return;
}
if (hasActiveObservers()) {
e.plug();
}
}
MediatorLiveData 类是LiveData的子类,它的addSource()方法将传进来的LiveData和onChanged封装到Source类中。如果MediatorLiveData有活跃观察者,就调用plug()方法。
// MediatorLiveData 类源码
private static class Source<V> implements Observer<V> {
final LiveData<V> mLiveData;
final Observer<? super V> mObserver;
int mVersion = START_VERSION;
Source(LiveData<V> liveData, final Observer<? super V> observer) {
mLiveData = liveData;
mObserver = observer;
}
void plug() {// 注释1
mLiveData.observeForever(this);
}
void unplug() {
mLiveData.removeObserver(this);
}
@Override
public void onChanged(@Nullable V v) {
if (mVersion != mLiveData.getVersion()) {
mVersion = mLiveData.getVersion();
// 注释2
mObserver.onChanged(v);
}
}
}
// LiveData 类源码
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
// 注释3
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
Source是MediatorLiveData的内部类,是对源LiveData的包装。注释1处Source的plug方法会调用LiveData的observeForever方法。
注释2处Transformations.map方法传入的Observer的回调方法onChanged()会在此调用。
注释3处用AlwaysActiveObserver来对Observer进行包装,紧接着调用AlwaysActiveObserver的activeStateChanged方法,其内部实际调用的是ObserverWrapper的activeStateChanged方法。
下面,接着看AlwaysActiveObserver 源码
// LiveData 类源码
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
AlwaysActiveObserver是LiveData的内部类,它继承自ObserverWrapper。从shouldBeActive()方法返回true,可以看出AlwaysActiveObserver和ObserverWrapper相比来说,它是永远处于Active状态的。