MediatorLiveData 中介者LiveData,
- 它可以監(jiān)聽另一個LiveData的數(shù)據(jù)變化,
- 同時也可以做為一個liveData,被其他Observer觀察。
一、基本用法
ViewModel中定義MediatorLiveData
val mediator = MediatorLiveData<List<String>>();
val strLive = MutableLiveData<List<String>>();
//(1)為mediator addSource,監(jiān)聽其他的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)監(jiān)聽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) 方法,接收兩個參數(shù)LiveData 和Observer。
- 首先會將LiveData 和Observer封裝成一個Source對象
- 然后在MediatorLiveData 自身存在活躍態(tài)的Observer時, 會將Source的plug()
if (hasActiveObservers()) {
e.plug();
}
Source的plug方法 會為參數(shù)liveData以O(shè)bserverForever()的方式添加一個Observer。監(jiān)聽到數(shù)據(jù)變化會傳遞到參數(shù)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數(shù)據(jù)傳遞到了Observer回調(diào)中
//(1)為mediator addSource,監(jiān)聽其他的liveData
mediator.addSource(strLive, Observer {
Log.i("ccccccccccc","onchange"+it.size);
mediator.value = it
})
通過為mediator.value賦值,將數(shù)據(jù)變化傳遞到mediator的Observer中
//(2)監(jiān)聽mediaLiveData
viewModel.mediator.observe(this, Observer {
Log.i("ccccccccc","size==="+it.size)
})