Android Transformations分析
前言
之前看大佬对于这个类的解析是站在他们的角度分析的,作为初学者刚开始的时候有点看不懂,看过源码之后来记录一下心得,这个类的基础是LiveData,是一个带有生命周期控制的观察者模式框架,不清楚的小伙伴可以把它当作一个回调。
Map与switchMap
目前只分析这两个方法,第三个方法时后加的。
Map
首先来看方法参数及返回值:
- 运行于主线程的静态方法
- 两个参数,第一个参数为一个LiveData对象,第二个参数为一个function接口,观察接口可知只有一个方法apply,对象泛型的第一个参数类型为方法的入参类型,第二个参数类型为方法的出参类型。
- 返回值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);
}
方法体
方法体很简单:
- 创建一个MediatorLiveData对象。
- 执行该对象的addSource方法,参数为一个LiveData和一个Observer。
- 将这个对象返回。
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方法的时候才会最终执行。