MediatorLiveData

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

三、參考文章

http://www.itdecent.cn/p/5c5cef61677f

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 懶得處理樣式了, 將就著看吧. 官網(wǎng)地址: https://developer.android.com/topic...
    Reddington_604e閱讀 1,906評論 0 1
  • 1.關(guān)于MediatorLiveData的addSource()方法 從注釋來看,addSource()是add一...
    島在深海處閱讀 11,150評論 2 11
  • 引子—— 在Android開發(fā)中,為了避免ANR,通常耗時的操作(網(wǎng)絡(luò)請求、數(shù)據(jù)庫操作)都會在子線程中執(zhí)行,執(zhí)行完...
    月影秋閱讀 2,366評論 0 0
  • 朋友圈兒里有人發(fā)了個找孩子的消息,接著議論就來了,有罵街的,又tm糊弄人,哪兒有的事兒?。挥辛ψC這事兒是事實的,說...
    和自己賽跑的蝸牛閱讀 788評論 12 13
  • 納 涼 一位老者坐塘邊, 一本閑書翻半天。 一把舊扇搖清爽, 一片樹陰聞鳴蟬。
    憨牛_713c閱讀 346評論 0 3

友情鏈接更多精彩內(nèi)容