RxJava系列文章目录导读:

一、RxJava create操作符的用法和源码分析

二、RxJava map操作符用法详解

三、RxJava flatMap操作符用法详解

四、RxJava concatMap操作符用法详解

五、RxJava onErrorResumeNext操作符实现app与服务器间token机制

六、RxJava retryWhen操作符实现错误重试机制

七、RxJava 使用debounce操作符优化app搜索功能

八、RxJava concat操作处理多数据源

九、RxJava zip操作符在Android中的实际使用场景

十、RxJava switchIfEmpty操作符实现Android检查本地缓存逻辑判断

十一、RxJava defer操作符实现代码支持链式调用

十二、combineLatest操作符的高级使用

十三、RxJava导致Fragment Activity内存泄漏问题

flatMap操作符的作用

官方文档解释:

Returns an Observable that emits items based on applying a function that you supply to each item emitted by the source Observable, where that function returns an Observable, and then merging those resulting Observables and emitting the results of this merger.
  • 1

官方流程图:

对Observable发射的数据都应用(apply)一个函数,这个函数返回一个Observable,然后合并这些Observables,并且发送(emit)合并的结果。 flatMap和map操作符很相像,flatMap发送的是合并后的Observables,map操作符发送的是应用函数后返回的结果集

flatMap操作符使用示例

继续map操作符的案例

还是以上一篇map操作符的例子吧,如果对map操作符不是很了解的可以点击链接去看看。获取主机的IP地址:

   private Observable<String> processUrlIpByOneFlatMap() {return Observable.just("http://www.baidu.com/","http://www.google.com/","https://www.bing.com/").flatMap(new Func1<String, Observable<String>>() {@Overridepublic Observable<String> call(String s) {return createIpObservable(s);}}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<String>() {@Overridepublic void call(String s) {printLog(tvLogs, "Consume Data <- ", s);}}, new Action1<Throwable>() {@Overridepublic void call(Throwable throwable) {printErrorLog(tvLogs, "throwable call()", throwable.getMessage());}});}//根据主机获取ipprivate Observable<String> createIpObservable(final String url) {return Observable.create(new Observable.OnSubscribe<String>() {@Overridepublic void call(Subscriber<? super String> subscriber) {try {String ip = getIPByUrl(url);subscriber.onNext(ip);printLog(tvLogs, "Emit Data -> ",url+" : " +ip);} catch (MalformedURLException e) {e.printStackTrace();//subscriber.onError(e);subscriber.onNext(null);} catch (UnknownHostException e) {e.printStackTrace();//subscriber.onError(e);subscriber.onNext(null);}subscriber.onCompleted();}});}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

输出结果:

Emit Data -> 'http://www.baidu.com/ : 115.239.211.112'
Main Thread:false, Thread Name:RxCachedThreadScheduler-1
Consume Data <- '115.239.211.112'
Main Thread:true, Thread Name:mainEmit Data -> 'http://www.google.com/ : 216.58.199.100'
Main Thread:false, Thread Name:RxCachedThreadScheduler-1
Consume Data <- '216.58.199.100'
Main Thread:true, Thread Name:mainEmit Data -> 'https://www.bing.com/ : 202.89.233.104'
Main Thread:false, Thread Name:RxCachedThreadScheduler-1
Consume Data <- '202.89.233.104'
Main Thread:true, Thread Name:main
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

flatMap进阶使用

我们从上面的输出结果可以看出,效果和使用map操作符的效果是一样。 
我们同时也发现线程的名称(Thread Name)都是 RxCachedThreadScheduler-1 ,说明他们是通过一个线程来完成所有的任务的。 
如果任务很多,仅仅通过一个线程去做,效率上是不是有点低呢?如果我想使用多个线程来完成这些任务该怎么做呢? 
很简单,只需要在创建Observable的时候加上subscribeOn(Schedulers.io()) 即可。完整代码如下:

//根据主机获取ipprivate Observable<String> createIpObservable(final String url) {return Observable.create(new Observable.OnSubscribe<String>() {@Overridepublic void call(Subscriber<? super String> subscriber) {try {String ip = getIPByUrl(url);subscriber.onNext(ip);printLog(tvLogs, "Emit Data -> ",url+" : " +ip);} catch (MalformedURLException e) {e.printStackTrace();//subscriber.onError(e);subscriber.onNext(null);} catch (UnknownHostException e) {e.printStackTrace();//subscriber.onError(e);subscriber.onNext(null);}subscriber.onCompleted();}}).subscribeOn(Schedulers.io());}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

看下运行效果:

“` 
Consume Data <- ‘202.89.233.103’ 
Main Thread:true, Thread Name:main 
Emit Data -> ‘https://www.bing.com/ : 202.89.233.103’ 
Main Thread:false, Thread Name:RxCachedThreadScheduler-8

Emit Data -> ‘http://www.google.com/ : 216.58.203.36’ 
Main Thread:false, Thread Name:RxCachedThreadScheduler-7 
Consume Data <- ‘216.58.203.36’ 
Main Thread:true, Thread Name:main

Emit Data -> ‘http://www.baidu.com/ : 115.239.211.112’ 
Main Thread:false, Thread Name:RxCachedThreadScheduler-6 
Consume Data <- ‘115.239.211.112’ 
Main Thread:true, Thread Name:main 
“`

从运行可以看出,执行完成任务的不是一个线程了,而是三个不同的线程 RxCachedThreadScheduler-8RxCachedThreadScheduler-7RxCachedThreadScheduler-6 。

但是发现一个问题,输出的结果的顺序乱了,不是我们输入的baidu.com/google.com/bing.com顺序了。

那怎么办呢?

这时候concatMap操作符就闪亮登场了,下一篇将介绍concatMap操作符的用法。

RxJava flatMap操作符用法详解相关推荐

  1. c语言right,C++ left和right操作符用法详解

    正如学习fixed.setprecision 和 showpoint 时的代码示例所看到的,cout 的输出是右对齐的,这意味着如果打印的字段大于显示的值,则值会被打印在字段的最右侧,带有前导空格. ...

  2. Linux下的awk用法详解

    Linux下的awk用法详解 一.awk介绍 二.awk的语法 三.awk常见用法 四.awk其他用法 五.awk语言特性 一.awk介绍 1.AWK 是一种处理文本文件的语言,是一个强大的文本分析工 ...

  3. this指针用法详解

    C++中this指针的用法详解 2010-11-12 20:40:45 分类: C/C++ 1. this指针的用处: 一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果 ...

  4. 优先队列priority_queue 用法详解

    优先队列priority_queue 用法详解 优先队列是队列的一种,不过它可以按照自定义的一种方式(数据的优先级)来对队列中的数据进行动态的排序 每次的push和pop操作,队列都会动态的调整,以达 ...

  5. STL中map和string, vector 用法详解

    1. map 用法详解 std map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成 ...

  6. oracle中取反_oracle正则表达式regexp_like的用法详解

    oracle正则表达式regexp_like的用法详解 更新时间:2013年06月13日 17:42:05   作者: 本篇文章是对oracle正则表达式regexp_like的用法进行了详细的分析介 ...

  7. sizeof,strlen用法详解

    sizeof 前向声明: sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着"辛苦我一个,幸福千万人"的伟大思想,我决定将其尽可能详细的总结一下. 但 ...

  8. Variant 用法详解

    Variant 用法详解 在你的程序中使用 variant,要包含头文件 "boost/variant.hpp".这个头文件包含了整个库,所以你不必知道要使用哪些单独的特性:以后, ...

  9. sort在c语言中的作用,c语言中sort的用法详解.docx

    c语言中sort的用法详解.docx C语言中SORT的用法详解C语言的学习很多是比较复杂的,那么C语言中SORT的用法的用法你知道吗下面学习啦小编就跟你们详细介绍下C语言中SORT的用法的用法,希望 ...

最新文章

  1. 【JAVA小游戏+水果售卖系统】基于GUI界面编程的水果“人生”模拟系统
  2. 【Python】WindowsError的错误代码详解
  3. Eclipse中弹出OLE Exception窗口
  4. postman使用指南
  5. SqlServer表中两条全然同样的记录,怎样删除当中1条
  6. 吴恩达深度学习4.4练习_Convolutional Neural Networks_Face Recognition for the Happy House
  7. 卷积神经网络-加载数据集
  8. (第十一周)俄罗斯方块测试报告
  9. java t800,T800KPI绩效考核系统C#源码
  10. 不到100行代码搞定Python做OCR识别身份证,文字等各种字体
  11. 42表盘直径是从哪测量_手表的术语中,直径指的是外观直径还是表盘直径?
  12. Unity实战篇 | 游戏中控制 地图无限自动化生成 的方法,进一步优化项目
  13. 如何修改文件格式(win11)
  14. 无线认证 服务器是怎么回事,无线wifi认证服务器参数设置方法是什么
  15. RabbitMQ(三)发布确认 Publisher Confirms
  16. js实现语音播报+html自动播放音频
  17. 别踩白块_前端H5游戏毕设
  18. guess在Java中用法_猜一猜,guess有哪些用法?
  19. 经过JDBC毗邻oracle数据库的十年夜才干
  20. etcd学习和实战:3、go使用etcd实现服务发现和管理

热门文章

  1. openwrt 遍译php_完全新手教程:编译openwrt全过程
  2. matlab中读文件的行数_[转载]MATLAB中获取大型文本文件行数方法研究(转)
  3. python爬虫 django搜索修改更新数据_django_数据库操作—增、删、改、查
  4. 联想m7400pro更换墨粉盒怎么清零_打印耗材到底怎么选
  5. php 进度条百分比算法,实例讲解Ajax实现简单带百分比进度条
  6. fibonacci数列前20项_等差数列、等比数列、调和数列等几种常见数列的总结
  7. c#同步 oracle数据,利用C#实现数据同步功能 | 学步园
  8. mysql命令行批量添加数据_mysql命令行批量插入100条数据命令
  9. 简单动态启停图 js jquery css3
  10. Android源码解析(一)动画篇-- Animator属性动画系统