Android Transformations分析

前言

之前看大佬对于这个类的解析是站在他们的角度分析的,作为初学者刚开始的时候有点看不懂,看过源码之后来记录一下心得,这个类的基础是LiveData,是一个带有生命周期控制的观察者模式框架,不清楚的小伙伴可以把它当作一个回调。

Map与switchMap

目前只分析这两个方法,第三个方法时后加的。

Map

首先来看方法参数及返回值:

  1. 运行于主线程的静态方法
  2. 两个参数,第一个参数为一个LiveData对象,第二个参数为一个function接口,观察接口可知只有一个方法apply,对象泛型的第一个参数类型为方法的入参类型,第二个参数类型为方法的出参类型。
  3. 返回值LiveData的泛型实际类型为Function的apply方法的返回类型一致。
@MainThread
    public static <X, Y> LiveData<Y> map(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, Y> mapFunction)
public interface Function<I, O> {
    /**
     * Applies this function to the given input.
     *
     * @param input the input
     * @return the function result.
     */
    O apply(I input);
}

方法体

方法体很简单:

  1. 创建一个MediatorLiveData对象。
  2. 执行该对象的addSource方法,参数为一个LiveData和一个Observer。
  3. 将这个对象返回。
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;

首先就是这个Observer,直译就是观察者,可以类比普通的回调接口,相当于我们在这里实现了一个回调,那么它必然要在某个地方被注册才能进行使用。结合方法名为addSource,以及onChange里是result的方法,我们在这里推测是将这个Observer注册给source对象。

public interface Observer<T> {
    /**
     * Called when the data is changed.
     * @param t  The new data
     */
    void onChanged(T t);
}

那么现在还有一个问题就是MediatorLiveData,可以跳过switchMap去看(这两个方法差不多)。

switchMap

这个方法和上一个很像,区别就是Function方法的第二个参数变为了指定为LiveData,其他的方面几乎不变,代表的意义也大差不差。

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

MediatorLiveData

这个类也很简单,它继承于MutableLiveData,也就是最终是LiveData,并且从它的类doc注释中我们很容易了解到这是为了更容易实现多个数据(LiveData)整合所提出的,我们接下来来看上面提到的addSource方法。
它会先创建一个内部类Source,然后执行mSources的putIfAbsent方法。mSources是一个map对象

private SafeIterableMap<LiveData<?>, Source<?>> mSources = new SafeIterableMap<>();

然后通过existing 判断当前的Source是否被存储过,知道现在还没有验证我们上面的猜测与问题,Observer在哪里注册的,其他方法我们就忽略,因为都不可能进行注册,只有最后的e.plug()最有可能。

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

果然,它执行了注册方法,至此我们看完了整个流程

void plug() {
            mLiveData.observeForever(this);
        }

总结

其实就是把一个LiveData转化为另一个LiveData使用,可以类比为回调异步链的调用,source的LiveDta执行onchange的时候,result的LiveData执行setValue方法。另外,使用MediatorLiveData只是单纯的使用他的方法,并没有使用它最主要的合并数据的特性(这也是我一直迷的点,我之前一直在找外部是怎么利用数据整合的)。

还有最重要的一点就是Function方法的执行时机

经过分析之后应该都可以明白了,类比回调,他也是会在source执行onChange方法的时候才会最终执行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值