作用
- MediatorLiveData 可以接管普通的 LiveData,使得当 LiveData 有数据更新的时候,MediatorLiveData 也能够 “收到响应”
实例
class mainactivity : appcompatactivity{
private val originData = MutableLiveData<String>()
private val mediatorLiveData = MediatorLiveData<String>()
override fun onCreate(savedInstanceState: Bundle?) {
mediatorLiveData.addSource(originData, Observer<String>{
Log.e("==>liveData","addSourceObserver:$it")
})
btn.setOnClickListener {
originData.value = "Hello"
}
}
说明
-
1.构建一个 MediatorLiveData对象,并通过addSource()将originData对象传入,然后添加回调方法,当我们点击按钮的时候,设置originData的值,最后在控制台应该输出:==>liveData: addSourceObserver:Hello。但是最后发现却没有输出,那是因为MediatorLiveData对象没有被“激活”,mediatorLiveData需要调用observe() 或者 observeForever() 方法来进行激活
override fun onCreate(savedInstanceState: Bundle?) { ... ... mediatorLiveData.observe(this, Observer { Log.e("==>liveData","mediatorLiveData:$it") }) ... ... }
说明
-
当再次点击按钮时,其输出不是:
==>liveData: addSourceObserver:Hello ==>liveData: mediatorLiveData:Hello
实际输出是:
==>liveData: addSourceObserver:Hello
那么为什么会这样了,那我们看看源码到底发生了什么?
private static class Source<V> implements Observer<V> {
//传递过来的liveData
final androidx.lifecycle.LiveData<V> mLiveData;
//构建的observer
final Observer<? super V> mObserver;
//当前observer的版本
int mVersion = START_VERSION;
/**
* 通过构造函数获取传递进来的livedata以及观察者
* @param liveData
* @param observer
*/
Source(LiveData<V> liveData, final Observer<? super V> observer) {
mLiveData = liveData;
mObserver = observer;
}
/**
* 让传递进来的livedata添加一个不对生命周期进行管理的观察者
*/
void plug() {
mLiveData.observeForever(this);
}
/**
* 让传递进来的livedata移除观察者
*/
void unplug() {
mLiveData.removeObserver(this);
}
/**
* 传递进来的livedata添加了一个不进行生命周期管理的观察者(source),
* 当livedata设置数据数据时会去通知所有的观察者,包括source
* source就会回调构建的observer的onChanged()方法,
* 那么livedata设置数据后那么observer就会获取到数据
* @param v
*/
@Override
public void onChanged(@Nullable V v) {
if (mVersion != mLiveData.getVersion()) {
mVersion = mLiveData.getVersion();
mObserver.onChanged(v);
}
}
}
说明
-
1.继承于Observer,是Observer的子类
-
2.持有传递进来的livedata和observer对象的引用
-
3.plug():让传递进来的livedata添加一个不对生命周期进行管理的观察者
-
4.unplug():传递进来的livedata移除观察者。
-
5.onChanged():当传递进来的livedata有数据要通知所有观察者时,当前Observer会触发onChanged()方法,之后就会发送给传递进来的mObserver
//map 能保证在遍历的时候可以修改集合 key:LiveData value:Source private SafeIterableMap<androidx.lifecycle.LiveData<?>, Source<?>> mSources = new SafeIterableMap<>(); /** * 添加获取一个livedata * @param source * @param onChanged * @param <S> */ @MainThread public <S> void addSource(@NonNull androidx.lifecycle.LiveData<S> source, @NonNull Observer<? super S> onChanged) { //构建source对象(Observer),封装了传递进来的livedata和observer Source<S> e = new Source<>(source, onChanged); //若同一个livedata的观察者不是同一个将会抛异常 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; } //需要有激活状态的观察者才可以添加source观察者 // 那么要是我先调用了addSource 再调用observer()那么不是也不能触发e.plug()了吗 if (hasActiveObservers()) { e.plug(); } } /** * Stops to listen the given {@code LiveData}. * * @param toRemote {@code LiveData} to stop to listen * @param <S> the type of data hold by {@code source} LiveData */ @MainThread public <S> void removeSource(@NonNull androidx.lifecycle.LiveData<S> toRemote) { Source<?> source = mSources.remove(toRemote); if (source != null) { source.unplug(); } } /** * 1.重写了onActive()方法 * 2.触发条件:当livedata有第一个观察者后调用 * 3.因此当我们先调用source(),然后再调用observer(),也可以触发plug(), * 让source作为观察者被添加到livedata中 */ @CallSuper @Override protected void onActive() { for (Map.Entry<androidx.lifecycle.LiveData<?>, Source<?>> source : mSources) { source.getValue().plug(); } } /** * 1.重写了onInactive()方法 * 2.触发条件:当livedata没有处于激活状态的观察者后 * 3.解除绑定 */ @CallSuper @Override protected void onInactive() { for (Map.Entry<androidx.lifecycle.LiveData<?>, Source<?>> source : mSources) { source.getValue().unplug(); } }
说明
- 1.mSources:以livedata为key,以封装了livedata和observer的Source为value
- 2.addSource():将livedata和observer封装成Source对象,然后存储到mSources中,然后调用hasActiveObservers()判断是否有激活状态的观察者,若有则调用e.plug()给livedata注册一个不进行生命周期绑定的观察者
- 3.removeSource():从mSources中移除对应的观察者
- 4.onActive():当有第一个处于激活状态的观察者的时候触发,因为有可能先调用addSource(),然后再调用observer(),导致在addSource()中中无法触发e.plug(),那么只有在这里触发进行注册了。
- 5.onInactive() :livedata没有处于激活状态的观察者后触发,可以用于解除观察者的绑定