Android Transformations分析
Android Transformations分析
- 前言
- Map与switchMap
- Map
- 首先来看方法参数及返回值:
- 方法体
- switchMap
- MediatorLiveData
- 总结
- 还有最重要的一点就是Function方法的执行时机
前言
之前看大佬对于这个类的解析是站在他们的角度分析的,作为初学者刚开始的时候有点看不懂,看过源码之后来记录一下心得,这个类的基础是LiveData,是一个带有生命周期控制的观察者模式框架,不清楚的小伙伴可以把它当作一个回调。
Map与switchMap
目前只分析这两个方法,第三个方法时后加的。
Map
首先来看方法参数及返回值:
- 运行于主线程的静态方法
- 两个参数,第一个参数为一个LiveData对象,第二个参数为一个function接口,观察接口可知只有一个方法apply,对象泛型的第一个参数类型为方法的入参类型,第二个参数类型为方法的出参类型。
- 返回值LiveData的泛型实际类型为Function的apply方法的返回类型一致。
@MainThreadpublic 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>() {@Overridepublic 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>() {@Overridepublic 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()最有可能。
@MainThreadpublic <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方法的时候才会最终执行。
Android Transformations分析相关推荐
- android逆向分析概述_Android存储概述
android逆向分析概述 Storage is this thing we are all aware of, but always take for granted. Not long ago, ...
- Android JNI入门第五篇——Android.mk分析
转载请标明出处: http://blog.csdn.net/michael1112/article/details/56671708 江东橘子的博客 Android.mk文件是在使用NDK编译C代码时 ...
- Android多线程分析之二:Thread的实现
Android多线程分析之二:Thread的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前文<Android多线程分析之一:使 ...
- Android内存分析和调优(上)
Android内存分析和调优(上) Android内存分析和调优(上) Android内存分析工具(四):adb命令 posted on 2017-09-25 19:29 时空观察者9号 阅读(... ...
- Android Telephony分析(七) ---- 接口扩展(异步转同步)
本文是基于上一篇<Android Telephony分析(六) -- 接口扩展(实践篇)>来写的. 上一篇介绍的接口扩展的方法需要实现两部分代码: 1. 从APP至RIL,发送请求: ...
- Android Telephony分析(六) ---- 接口扩展(实践篇)
本文将结合前面五篇文章所讲解的知识,综合起来,实现一个接口扩展的功能. 如果还没有阅读过前面五篇文章的内容,请先阅读: <Android Telephony分析(一) - Phone详解 & ...
- Android Telephony分析(五) ---- TelephonyRegistry详解
本文紧接着上一篇文章<Android Telephony分析(四) -- TelephonyManager详解 >的1.4小节. 从TelephonyRegistry的大部分方法中: ...
- Android Telephony分析(三) ---- RILJ详解
前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程. 这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\And ...
- Android Telephony分析(二) ---- RegistrantList详解
前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程. 在Telephony模块中,在RIL.Tracker(ServiceStateTr ...
最新文章
- oracle数据加载控制文件格式,oracle数据加载的几种常用方法
- 现代浏览器的工作原理
- BinaryStar代码分析前言
- python切割图像,使用Python图像库将一个图像切割成多个图像
- 2017 ACM-ICPC南宁网络赛: J. Minimum Distance in a Star Graph(BFS)
- 工业大数据发展面临四方面挑战
- STM32学习笔记(十) CAN通讯测试(环回模式)
- CentOS7 一键安装KMS服务【整理】
- 双非上岸北大计算机,双非二战考研上岸北大汇丰经验贴
- CIO峰会:企业私有云存储实践方案
- SRE(运维工程师)一文详解技术体系和架构师成长之路
- 禁用鼠标cusor:no-drop与cursor:not-allowed区别与认识
- 子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环10 次(线程面试:windows下实现)
- 前端使用高德地图url实现地图定位
- 软件测试117道面试题直击面试官灵魂
- 百度爱番番实时CDP建设实践
- “兼职发明家召集令”
- 2021年三季度中国食品加工行业A股上市企业营收排行榜:双汇发展再度蝉联榜单TOP1,4家企业新上榜(附热榜TOP19详单)
- [数据结构][Python]鸡尾酒排序、桶排序
- SAP 教程之 02 如何为 Inbound IDOC 配置 SAP