Android Transformations分析

  • 前言
  • Map与switchMap
    • Map
      • 首先来看方法参数及返回值:
      • 方法体
    • switchMap
  • MediatorLiveData
  • 总结
    • 还有最重要的一点就是Function方法的执行时机

前言

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

Map与switchMap

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

Map

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

  1. 运行于主线程的静态方法
  2. 两个参数,第一个参数为一个LiveData对象,第二个参数为一个function接口,观察接口可知只有一个方法apply,对象泛型的第一个参数类型为方法的入参类型,第二个参数类型为方法的出参类型。
  3. 返回值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);
}

方法体

方法体很简单:

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

  1. android逆向分析概述_Android存储概述

    android逆向分析概述 Storage is this thing we are all aware of, but always take for granted. Not long ago, ...

  2. Android JNI入门第五篇——Android.mk分析

    转载请标明出处: http://blog.csdn.net/michael1112/article/details/56671708 江东橘子的博客 Android.mk文件是在使用NDK编译C代码时 ...

  3. Android多线程分析之二:Thread的实现

    Android多线程分析之二:Thread的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前文<Android多线程分析之一:使 ...

  4. Android内存分析和调优(上)

    Android内存分析和调优(上) Android内存分析和调优(上) Android内存分析工具(四):adb命令 posted on 2017-09-25 19:29 时空观察者9号 阅读(... ...

  5. Android Telephony分析(七) ---- 接口扩展(异步转同步)

    本文是基于上一篇<Android Telephony分析(六) -- 接口扩展(实践篇)>来写的.  上一篇介绍的接口扩展的方法需要实现两部分代码:  1. 从APP至RIL,发送请求:  ...

  6. Android Telephony分析(六) ---- 接口扩展(实践篇)

    本文将结合前面五篇文章所讲解的知识,综合起来,实现一个接口扩展的功能.  如果还没有阅读过前面五篇文章的内容,请先阅读:  <Android Telephony分析(一) - Phone详解 & ...

  7. Android Telephony分析(五) ---- TelephonyRegistry详解

    本文紧接着上一篇文章<Android Telephony分析(四) -- TelephonyManager详解 >的1.4小节.  从TelephonyRegistry的大部分方法中:  ...

  8. Android Telephony分析(三) ---- RILJ详解

    前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程.  这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\And ...

  9. Android Telephony分析(二) ---- RegistrantList详解

    前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程.  在Telephony模块中,在RIL.Tracker(ServiceStateTr ...

最新文章

  1. oracle数据加载控制文件格式,oracle数据加载的几种常用方法
  2. 现代浏览器的工作原理
  3. BinaryStar代码分析前言
  4. python切割图像,使用Python图像库将一个图像切割成多个图像
  5. 2017 ACM-ICPC南宁网络赛: J. Minimum Distance in a Star Graph(BFS)
  6. 工业大数据发展面临四方面挑战
  7. STM32学习笔记(十) CAN通讯测试(环回模式)
  8. CentOS7 一键安装KMS服务【整理】
  9. 双非上岸北大计算机,双非二战考研上岸北大汇丰经验贴
  10. CIO峰会:企业私有云存储实践方案
  11. SRE(运维工程师)一文详解技术体系和架构师成长之路
  12. 禁用鼠标cusor:no-drop与cursor:not-allowed区别与认识
  13. 子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环10 次(线程面试:windows下实现)
  14. 前端使用高德地图url实现地图定位
  15. 软件测试117道面试题直击面试官灵魂
  16. 百度爱番番实时CDP建设实践
  17. “兼职发明家召集令”
  18. 2021年三季度中国食品加工行业A股上市企业营收排行榜:双汇发展再度蝉联榜单TOP1,4家企业新上榜(附热榜TOP19详单)
  19. [数据结构][Python]鸡尾酒排序、桶排序
  20. SAP 教程之 02 如何为 Inbound IDOC 配置 SAP

热门文章

  1. 液压控制系列之活塞位置测量(带原点标定功能)
  2. Java开发框架!java枚举定义lists参数
  3. python开发面试问题及答案_集锦 | 53个Python面试问题 答案打包带走
  4. FreeRADIUS ACCT_USERS说明
  5. 帆软报表如何调整软件字体?字体太小看不清怎么办?
  6. 一起自学SLAM算法:3.4 图像特征点提取
  7. 拒绝日夜调参:超参数搜索算法一览
  8. 制作一个简易的自主夹取机械臂
  9. MVC设计模式、单体架构、前后端分离、微服务
  10. Unity 打包成APK部分安卓机黑屏