前言

  • Rxjava,由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎。
Github截图

如果还不了解 RxJava,请看文章:Android:这是一篇 清晰 & 易懂的Rxjava 入门教程

  • RxJava如此受欢迎的原因,在于其提供了丰富 & 功能强大的操作符,几乎能完成所有的功能需求
  • 今天,我将为大家详细介绍RxJava操作符中最常用的变换操作符,并附带 Retrofit 结合 RxJava的实例Demo教学,希望你们会喜欢。
  1. 本系列文章主要基于 Rxjava 2.0
  2. 接下来的时间,我将持续推出 AndroidRxjava 2.0 的一系列文章,包括原理、操作符、应用场景、背压等等 ,有兴趣可以继续关注Carson_Ho的安卓开发笔记!!
示意图

目录

示意图

1. 作用

  • 对事件序列中的事件 / 整个事件序列 进行加工处理(即变换),使得其转变成不同的事件 / 整个事件序列
  • 具体原理如下
示意图

2. 类型

  • RxJava中常见的变换操作符如下:

    示意图

  • 下面,我将对每种操作符进行详细介绍

注:本文只讲解RxJava2在开发过程中常用的变换操作符


3. 应用场景 & 对应操作符 介绍

  • 下面,我将对 RxJava2 中的变换操作符进行逐个讲解
  • 注:在使用RxJava 2操作符前,记得在项目的Gradle中添加依赖:
dependencies {      compile 'io.reactivex.rxjava2:rxandroid:2.0.1'      compile 'io.reactivex.rxjava2:rxjava:2.0.7'      // 注:RxJava2 与 RxJava1 不能共存,即依赖不能同时存在}

3.1 Map()

  • 作用
    对 被观察者发送的每1个事件都通过 指定的函数 处理,从而变换成另外一种事件

即, 将被观察者发送的事件转换为任意的类型事件。

  • 原理
示意图
  • 应用场景
    数据类型转换
  • 具体使用
    下面以将 使用Map() 将事件的参数从 整型 变换成 字符串类型 为例子说明
示意图
 // 采用RxJava基于事件流的链式操作        Observable.create(new ObservableOnSubscribe() {            // 1. 被观察者发送事件 = 参数为整型 = 1、2、3            @Override            public void subscribe(ObservableEmitter emitter) throws Exception {                emitter.onNext(1);                emitter.onNext(2);                emitter.onNext(3);            }            // 2. 使用Map变换操作符中的Function函数对被观察者发送的事件进行统一变换:整型变换成字符串类型        }).map(new Function() {            @Override            public String apply(Integer integer) throws Exception {                return "使用 Map变换操作符 将事件" + integer +"的参数从 整型"+integer + " 变换成 字符串类型" + integer ;            }        }).subscribe(new Consumer() {            // 3. 观察者接收事件时,是接收到变换后的事件 = 字符串类型            @Override            public void accept(String s) throws Exception {                Log.d(TAG, s);            }        });
  • 测试结果
示意图

从上面可以看出,map() 将参数中的 Integer 类型对象转换成一个 String类型 对象后返回

同时,事件的参数类型也由 Integer 类型变成了 String 类型


3.2 FlatMap()

  • 作用:将被观察者发送的事件序列进行 拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送

  • 原理

  1. 为事件序列中每个事件都创建一个 Observable 对象;
  2. 将对每个 原始事件 转换后的 新事件 都放入到对应 Observable对象;
  3. 将新建的每个Observable 都合并到一个 新建的、总的Observable 对象;
  4. 新建的、总的Observable 对象 将 新合并的事件序列 发送给观察者(Observer
示意图
  • 应用场景
    无序的将被观察者发送的整个事件序列进行变换

  • 具体使用

// 采用RxJava基于事件流的链式操作        Observable.create(new ObservableOnSubscribe() {            @Override            public void subscribe(ObservableEmitter emitter) throws Exception {                emitter.onNext(1);                emitter.onNext(2);                emitter.onNext(3);            }            // 采用flatMap()变换操作符        }).flatMap(new Function>() {            @Override            public ObservableSource apply(Integer integer) throws Exception {                final List list = new ArrayList<>();                for (int i = 0; i < 3; i++) {                    list.add("我是事件 " + integer + "拆分后的子事件" + i);                    // 通过flatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件                    // 最终合并,再发送给被观察者                }                return Observable.fromIterable(list);            }        }).subscribe(new Consumer() {            @Override            public void accept(String s) throws Exception {                Log.d(TAG, s);            }        });
  • 测试结果


    示意图

注:新合并生成的事件序列顺序是无序的,即 与旧序列发送事件的顺序无关

3.3 ConcatMap()

  • 作用:类似FlatMap()操作符

  • FlatMap()的 区别在于:拆分 & 重新合并生成的事件序列 的顺序 = 被观察者旧序列生产的顺序

  • 原理

示意图
  • 应用场景
    有序的将被观察者发送的整个事件序列进行变换

  • 具体使用

// 采用RxJava基于事件流的链式操作        Observable.create(new ObservableOnSubscribe() {            @Override            public void subscribe(ObservableEmitter emitter) throws Exception {                emitter.onNext(1);                emitter.onNext(2);                emitter.onNext(3);            }            // 采用concatMap()变换操作符        }).concatMap(new Function>() {            @Override            public ObservableSource apply(Integer integer) throws Exception {                final List list = new ArrayList<>();                for (int i = 0; i < 3; i++) {                    list.add("我是事件 " + integer + "拆分后的子事件" + i);                    // 通过concatMap中将被观察者生产的事件序列先进行拆分,再将每个事件转换为一个新的发送三个String事件                    // 最终合并,再发送给被观察者                }                return Observable.fromIterable(list);            }        }).subscribe(new Consumer() {            @Override            public void accept(String s) throws Exception {                Log.d(TAG, s);            }        });
  • 测试结果


    示意图

注:新合并生成的事件序列顺序是有序的,即 严格按照旧序列发送事件的顺序


3.4 Buffer()

  • 作用
    定期从 被观察者(Obervable)需要发送的事件中 获取一定数量的事件 & 放到缓存区中,最终发送

  • 原理

示意图
  • 应用场景
    缓存被观察者发送的事件
  • 具体使用
    那么,Buffer()每次是获取多少个事件放到缓存区中的呢?下面我将通过一个例子来说明
// 被观察者 需要发送5个数字        Observable.just(1, 2, 3, 4, 5)                .buffer(3, 1) // 设置缓存区大小 & 步长                                    // 缓存区大小 = 每次从被观察者中获取的事件数量                                    // 步长 = 每次获取新事件的数量                .subscribe(new Observer>() {                    @Override                    public void onSubscribe(Disposable d) {                    }                    @Override                    public void onNext(List stringList) {                        //                        Log.d(TAG, " 缓存区里的事件数量 = " +  stringList.size());                        for (Integer value : stringList) {                            Log.d(TAG, " 事件 = " + value);                        }                    }                    @Override                    public void onError(Throwable e) {                        Log.d(TAG, "对Error事件作出响应" );                    }                    @Override                    public void onComplete() {                        Log.d(TAG, "对Complete事件作出响应");                    }                });
  • 测试结果
示意图
  • 过程解释

下面,我将通过一个图来解释Buffer()原理 & 整个例子的结果

示意图

至此,关于RxJava2中主要的变换操作符已经讲解完毕


4. 实际开发需求案例

  • 变换操作符的主要开发需求场景 = 嵌套回调(Callback hell
  • 下面,我将采用一个实际应用场景实例来讲解嵌套回调(Callback hell

具体请看文章Android RxJava 实际应用案例讲解:网络请求嵌套回调


5. Demo地址

上述所有的Demo源代码都存放在:Carson_Ho的Github地址:RxJava2_变换操作符

喜欢的麻烦点个star


6. 总结

  • 下面,我将用一张图总结 RxJava2 中常用的变换操作符
示意图
  • 接下来的时间,我将持续推出 AndroidRxjava 2.0 的一系列文章,包括原理、操作符、应用场景、背压等等 ,有兴趣可以继续关注Carson_Ho的安卓开发笔记!!
示意图

请点赞!因为你的鼓励是我写作的最大动力!

相关文章阅读

  • 操作符使用
    Android:这是一篇 清晰 & 易懂的Rxjava 入门教程
    Android RxJava:最基础的操作符详解 - 创建操作符
    Android RxJava:图文详解 变换操作符
    Android RxJava:组合 / 合并操作符 详细教程
    Android RxJava:功能性操作符 全面讲解
  • 实际应用讲解
    Android RxJava 实际应用讲解:(无条件)网络请求轮询
    Android RxJava 实际应用讲解:(有条件)网络请求轮询
    Android RxJava 实际应用讲解:网络请求嵌套回调
    Android RxJava 实际应用讲解:合并数据源
    Android RxJava 实际应用讲解:从磁盘 / 内存缓存中 获取缓存数据
    Android RxJava 实际应用讲解:联合判断
    Android RxJava:细说 线程控制(切换 / 调度 )(含Retrofit实例讲解)
    Android RxJava 实际应用讲解:网络请求出错重连(结合Retrofit)

欢迎关注Carson_Ho的!

不定期分享关于安卓开发的干货,追求短、平、快,但却不缺深度

更多相关文章

  1. Android学习中遇到的优秀文章的总结(持续更新)
  2. android绘图小结
  3. EventBus粘性事件
  4. 用Kotlin实现Android点击事件的方法
  5. Android(安卓)通用的下拉刷新,重温事件传递
  6. Android(安卓)应用程序窗体显示状态操作(requestWindowFeature()
  7. Android(安卓)TextView setText卡顿问题
  8. ubuntu下eclipse Android(安卓)ADT中SDK Manager中安装SDK失败的
  9. Android客户端性能优化

随机推荐

  1. 已有项目导入他人创建的flutter项目(andr
  2. Android开发之Android体系架构介绍
  3. android开发笔记之2012版辅助开发工具包(A
  4. Android和Linux的关系
  5. android adb工具
  6. Android(安卓)adb中命令的运行
  7. Android(安卓)串口通信开发笔记01
  8. 如何保证Android设备的安全性
  9. Android使用Jdbc连接远程数据库
  10. Android入门教程(三)之------导入现有And