Android Jetpack 架构组件(六) LiveData的MediatorLiveData & Transformations

LiveData在设计理念上参考了RxJava。

MediatorLiveData在LiveData的基础上,实现了合并多个LiveData的作用。

可以监听一个或多个LiveData的变化。同时转化数据。

MediatorLiveData也是LiveData, 也可以被监听。接到的是转化后的数据。

 

基本用法:

从getNameFromServer()取的值是"alan", 而MediatorLiveData做了转化后成了alan gong.

public class MyViewModel extends ViewModel {
    private MutableLiveData<String> nameLiveData;
    private MediatorLiveData<String> testLiveData;

    public MyViewModel() {
        testLiveData = new MediatorLiveData<>();
        testLiveData.addSource(liveEvent, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                testLiveData.postValue(s + " gong");
            }
        });

        getNameFromServer();
    }

    public MediatorLiveData<String> getTestLiveData() {
        return testLiveData;
    }

    private void getNameFromServer() {
        if (liveEvent == null) {
            liveEvent = new MutableLiveData<>();
        }
        liveEvent.setValue("alan");
    }
}

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(LayoutInflater.from(this));
        setContentView(binding.getRoot());

        ViewModelProvider provider = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory());
        MyViewModel myViewModel = provider.get(MyViewModel.class);
        binding.setViewModel(myViewModel);

        myViewModel.getTestLiveData().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                textView.setText(s);
            }
        });
    }
}

也可以通过AddSource()添加多个LiveData. 道理也是一样的。

原理解析:

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<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 <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged)

在addSource的方法签名中,onChanged就是source的间接监听对象。是addSource把它们结合在一起。

addSource把所有添加的LiveData整合到一起放在mSources 里面。

  public <S> void removeSource(@NonNull LiveData<S> toRemote)

移出通过addSource添加的LiveData对象

重点是 onActive() 和onInactive()

它们俩把mSource里面的LiveData们,开启/关闭监听。如果MediatorLiveData的状态是Active就开启监听,Inactive就关闭监听。

 

内部Source类

前面提到addSource里的onChanged是间接监听对象。那么实际直接监听对象就是这个内部类Source. Source对监听到data中转后再发给onChanged。

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

 

接下来讲一下Transformations:

MediatorLiveData只是初始封装,实际使用最多的还是Transformations。是在MediatorLiveData基础上实现数据转化,就像RxJava的map和flatMap。

public class Transformations {

    private Transformations() {
    }

    @MainThread
    public static <X, Y> LiveData<Y> map(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, Y> mapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            @Override
            public void onChanged(@Nullable X x) {
                result.setValue(mapFunction.apply(x));
            }
        });
        return result;
    }

    @MainThread
    public static <X, Y> LiveData<Y> switchMap(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, LiveData<Y>> switchMapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            LiveData<Y> mSource;

            @Override
            public void onChanged(@Nullable X x) {
                LiveData<Y> newLiveData = switchMapFunction.apply(x);
                if (mSource == newLiveData) {
                    return;
                }
                if (mSource != null) {
                    result.removeSource(mSource);
                }
                mSource = newLiveData;
                if (mSource != null) {
                    result.addSource(mSource, new Observer<Y>() {
                        @Override
                        public void onChanged(@Nullable Y y) {
                            result.setValue(y);
                        }
                    });
                }
            }
        });
        return result;
    }
}

   

public interface Function<I, O> {
    /**
     * Applies this function to the given input.
     *
     * @param input the input
     * @return the function result.
     */
    O apply(I input);
}

 

public static <X, Y> LiveData<Y> map(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, Y> mapFunction)

就是前面基础使用讲到的方式.

  public static <X, Y> LiveData<Y> switchMap(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, LiveData<Y>> switchMapFunction) 

实现了LiveData<Y>到LiveData<X>的转变。

具体的转变过程是开发者在interface Function<I, O>的O apply(I input);里实现。

Transformations使用如下:

      LiveData<String> nameLiveData = Transformations.map(myViewModel.liveEvent, new Function<String, String>() {
            @Override
            public String apply(String input) {
                return input + "alan";
            }
        });

        nameLiveData.observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                textViewName.setText(s);
            }
        });

       LiveData<Integer> agoLiveData = Transformations.switchMap(myViewModel.liveEvent, new Function<String, LiveData<Integer>>() {
            @Override
            public LiveData<Integer> apply(String input) {
                MutableLiveData<Integer> serverData = new MutableLiveData<Integer>();
                server.getServerData(serverData);//do business in background, and while get data, raise event.
                return serverData; // return first to UI or view model.
            }
        });

        agoLiveData.observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                textViewAge.setText(String.valueOf(integer));
            }
        });

 

以上是MediatorLiveData & Transformations的使用场景和原理。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值