MediatorLiveData 中介者LiveData,
- 它可以监听另一个LiveData的数据变化,
- 同时也可以做为一个liveData,被其他Observer观察。
一、基本用法
ViewModel中定义MediatorLiveData
val mediator = MediatorLiveData<List<String>>();
val strLive = MutableLiveData<List<String>>();
//(1)为mediator addSource,监听其他的liveData
mediator.addSource(strLive, Observer {
Log.i("ccccccccccc","onchange"+it.size);
mediator.value = it
})
Activity
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//(2)监听mediaLiveData
viewModel.mediator.observe(this, Observer {
Log.i("ccccccccc","size==="+it.size)
})
binding.btnGotoGarden.setOnClickListener{
viewModel.strLive.value = arrayListOf("1","22","333","4444","55555")
};
}
二、原理解析
MediatorLiveData 主要有四个方法
- addSource
- removeSource
- onActive
- onInactive
public class MediatorLiveData<T> extends MutableLiveData<T> {
private SafeIterableMap<LiveData<?>, Source<?>> mSources = new SafeIterableMap<>();
@MainThread
public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) { //新建一个Source并且将该Source的Observer传进去
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();
}
}
@MainThread
public <S> void removeSource(@NonNull LiveData<S> toRemote) {
Source<?> source = mSources.remove(toRemote);
if (source != null) {
source.unplug();
}
}
@CallSuper
@Override
protected void onActive() {
for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
source.getValue().plug();
}
}
@CallSuper
@Override
protected void onInactive() {
for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
source.getValue().unplug();
}
}
}
public void addSource(@NonNull LiveData source, @NonNull Observer<? super S> onChanged) 方法,接收两个参数LiveData 和Observer。
- 首先会将LiveData 和Observer封装成一个Source对象
- 然后在MediatorLiveData 自身存在活跃态的Observer时, 会将Source的plug()
if (hasActiveObservers()) {
e.plug();
}
Source的plug方法 会为参数liveData以ObserverForever()的方式添加一个Observer。监听到数据变化会传递到参数mObserver中。
如下,
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() {
mLiveData.observeForever(this);
}
void unplug() {
mLiveData.removeObserver(this);
}
@Override
public void onChanged(@Nullable V v) {
if (mVersion != mLiveData.getVersion()) {
mVersion = mLiveData.getVersion();
mObserver.onChanged(v);
}
}
}
此时liveData数据传递到了Observer回调中
//(1)为mediator addSource,监听其他的liveData
mediator.addSource(strLive, Observer {
Log.i("ccccccccccc","onchange"+it.size);
mediator.value = it
})
通过为mediator.value赋值,将数据变化传递到mediator的Observer中
//(2)监听mediaLiveData
viewModel.mediator.observe(this, Observer {
Log.i("ccccccccc","size==="+it.size)
})
网友评论