美文网首页Android
MediatorLiveData

MediatorLiveData

作者: feifei_fly | 来源:发表于2019-11-18 10:35 被阅读0次

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)
        })

三、参考文章

https://www.jianshu.com/p/5c5cef61677f

相关文章

网友评论

    本文标题:MediatorLiveData

    本文链接:https://www.haomeiwen.com/subject/ocyvictx.html