现在有很多的 RxJava 入门教程,但是大多数都是示例代码,并不能让人很快理解 RxJava 的原理和方法,这篇文章就用流水线来比喻 RxJava 的开发方式,看完这篇文章后你就能理解 RxJava 的概念啦。

为什么另写一篇 RxJava 的文章?

已经有很多 RxJava 的文章通过例子阐述了什么是 RxJava 以及怎么去用,但它们大多数只有代码。虽然也会通过类比来解释,例如最出名的就是“流”。通常情况下代码能完美地让人理解(我们都是程序员,对吧?),但是 RxJava 十分不同于以往的 Android 开发。在最开始时通过代码是很难让人理解的,用“流”来类比并不足够,即使是 marbles 的例子也还远远不够。我可以保证自己能理解,但对于别人,老实说,难道你们不需要更多结合实际的例子?难道你们不想在脑海中举一个例子来让自己更好地理解 RxJava 吗?我做了,并且我想和你们分享。

工厂流水线

好吧,我说谎了。为了理解 RxJava,我在脑海里举了不仅仅一个例子。例如我尝试观察动物园笼子的动物,尝试观察河流里的鱼,也尝试去观察蝙蝠侠里的犯罪(额,这不是现实生活中的,但不失为一个很好的例子)。但我还是认为工厂流水线是最好的例子。

需求

我们先想象下,我们需要写一款应用来展示动物们的信息,并且现在我需要在新的界面实现以下功能:

  • 三份关于猫的信息
  • 每份都是唯一的
  • 每份都应该少于 300 字符
  • 每份都配张猫的图片

启动流水线!

我们尝试通过流水线上的工人们的帮助实现那些功能。

1、首先我们需要启动产品处理进程。仅仅有流水线是不足够的 - 还需要有人去启动它。例如一个对结果感兴趣的产品经理

2、现在我们需要随机获得有关猫的信息。但怎么做呢?幸运的是这里有 API 能让我们很容易做到!真的是巧合么。。。?好吧,我们先通过 GET 方法获取这些信息。

3、现在我们需要处理来自 API 的响应。它是由 HTTP 状态码和一列有关猫的信息组成。我们并不需要状态码所以我们首先去除它并将信息列表传给下一个工人。

4、下一件要做的事就是将信息列表的信息一个个抽离出来。为什么要这么做?因为这样做方便下游的工人操作单个字符串(例如检查字符串是否过长)。

5、每条信息都是唯一的。下一个工人的任务是清除重复项。

6、每条信息都不能太长(少于 300 字符)

7、现在我们的信息是唯一的且长度也符合要求可数量太多了而我们仅仅需要 3 份。所以下一个工人应该清除多余的信息。

8、每条信息都有一张随机的猫的图片。

9、我们不应该将信息分批给产品经理,而是应该将这些信息打包成一个列表。

10、现在产品经理可以在屏幕上显示结果了。

这就是我们要做的。我们已经通过流水线上的工人完整地实现了全部功能并最后将结果显示到了屏幕上。

若用 RxJava 实现这些需求该怎么做呢?

RxJava 中存在很多可观察对象(它传出的数据可以被我们观察到)和观察者(它观察并处理可观察对象传出的数据)。在我们的例子里流水线就是可观察对象而产品经理就是观察者。需要注意的是观察者启动整个流水线这个步骤是十分重要的。如果没有观察者,流水线是不会启动的。

那么流水线上的工人算什么呢?在 RxJava 的世界里它们叫做操作符。它们的动作十分像工人 - 他们需要处理那些被传出的数据(例如仅仅让唯一的数据通过)

在代码世界实现流水线

很好。可这么多图片有卵用?代码终究还是代码并不是一条流水线,不是吗?

mCatFactsService.getCatFacts(100).map(catFactResponse -> catFactResponse.getFacts()).flatMap(catFacts -> Observable.from(catFacts)).distinct().filter(catFact -> catFact.length() <= 300).take(3).map(catFact -> new CatFactWithImage(catFact, getRandomCatImageId())).toList().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(mCatFactsAdapter::setCatFactWithImages, Throwable::printStackTrace);

这样就能通过 RxJava 实现流水线了。为了理解上面的代码你应该从上到下看一遍。每个动作都是独立运行的 - 一个接着一个。

  • mCatFactsService.getCatFacts(100) – 这个就是 GET 方法。在响应里我们获得一个封装了 HTTP 状态码以及一列猫的信息的对象。Observable (即可观察对象)将这个对象(我们叫它 CatFactResponse 吧) 封装起来,现在我们就可以用 RxJava 的操作符对它进行处理。
  • map(), flatMap(), distinct(), filter(), take(), toList() – 这些就是操作符。它们可以修改被传出的数据 - 一个接着一个。它们就像上面例子的图片中流水线上的工人。
  • subscribe() – 让一个 Observer (即观察者)去订阅一个 Observable。若没有这一步整个流水线都无法启动。
  • subscribeOn() – 告诉 Observable 当 subscribe() 方法被调用后它应该在哪个线程被启动。接着每个操作符都会在那个线程工作直到我们改变线程。
  • observeOn() – 改变下一个操作符的工作线程。每个在这个方法之后的操作符都会在它指定的新的线程里工作,直到我们通过别的 observeOn() 改变线程。

现在我们再仔细分析我们用过的每个操作符:

.map(new Func1<CatFactResponse, List<String>>() {@Overridepublic List<String> call(CatFactResponse catFactResponse) {return catFactResponse.getFacts();}})

有可能你会不适应那花俏的箭头所以我将完整的实现展开了(当然我们可以通过 Java8 的 lambda 表达式实现那种语法 - 详情见 retrolambda)。

正如你说看到的, mCatFactsService.getCatFacts() 返回一串数据并被传到 CatFactResponse 中,但因为现在我们不需要 HTTP 状态码,所以我们通过 MAP (转换)操作符将 CatFactResponse 对象转换成别的对象 - 在这个例子中是 List 对象。下一个操作符将会处理这个对象。

    .flatMap(new Func1<List<String>, Observable<? extends String>>() {@Overridepublic Observable<? extends String> call(List<String> catFacts) {return Observable.from(catFacts);}})

flatMap 操作符接受猫的信息列表作为参数,分别取出列表的每条数据并抛给下一个操作符。所以我们拿到并抛出的数据都是 FROM (来自)这个列表的。

    .distinct()

这个操作符用来处理重复项,并且它不会让任何已经通过的相同字符串再次通过。每个都是 DISTINCT (独特的)。

    .filter(new Func1<String, Boolean>() {@Overridepublic Boolean call(String catFact) {return catFact.length() <= 300;}})

filter 操作符就是个简单的对/错判断表达式。如果字符串太长,将无法通过。所以 filter 很显然是用来 FILTERS (过滤的)。

    .take(3)

take 操作符 TAKES (取出)指定数量的信息。

    .map(new Func1<String, CatFactWithImage>() {@Overridepublic CatFactWithImage call(String catFact) {return new CatFactWithImage(catFact, getRandomCatImageId());}})

另一个 map 操作符。在我们打包所有字符串之前我们应该为每个字符串添加张猫的图片。

    .toList()

现在我们可以打包所有 CatFactWithImage 对象 TO (成)一个 LIST (列表)了。

    .subscribe(new Observer<List<CatFactWithImage>>() {@Overridepublic void onCompleted() {//no-op}@Overridepublic void onError(Throwable e) {e.printStackTrace();}@Overridepublic void onNext(List<CatFactWithImage> catFactWithImages) {mCatFactsAdapter.setCatFactWithImages(catFactWithImages);}});

然后就是简单地将 list 对象传给 adapter 对象而已。

结论

RxJava 是款十分强大的工具。但不幸的是如果你之前没有通过“流”的形式写过代码你可能很难理解它并学会如何去用它。因为它十分不同于以往平常的安卓开发,所以我们需要一些比代码更形象的东西去理解它。我希望这篇文章能帮助你更好地理解 RxJava 是如何工作的。

本文为稀土掘金投稿,欢迎技术投稿、约稿,给文章纠错,请发送邮件至tangxy@csdn.net。
原文链接: RxJava – the production line
原文作者: Mateusz Budzar
译者: Sausure
校对者: lizhuo、Rocky

用工厂流水线的方式来理解RxJava的概念相关推荐

  1. java 流水线_用工厂流水线的方式来理解 RxJava 的概念

    为什么另写一篇 RxJava 的文章? 已经有很多RxJava的文章通过例子阐述了什么是 RxJava 以及怎么去用,但它们大多数只有代码.虽然也会通过类比来解释,例如最出名的就是"流&qu ...

  2. JAVA中FC什么意思_用工厂流水线的方式来理解 RxJava 的概念

    为什么另写一篇 RxJava 的文章? 已经有很多RxJava的文章通过例子阐述了什么是 RxJava 以及怎么去用,但它们大多数只有代码.虽然也会通过类比来解释,例如最出名的就是"流&qu ...

  3. 软件工厂流水线构建方式

    软件工厂流水线是一种自动化构建.测试.交付软件的工作流程,它的目的是尽可能减少人为干预,提高软件生产效率和质量.以下是软件工厂流水线的构建方式: 定义流水线阶段:软件工厂流水线可以分为多个阶段,如代码 ...

  4. 理解RxJava线程模型

    RxJava作为目前一款超火的框架,它便捷的线程切换一直被人们津津乐道,本文从源码的角度,来对RxJava的线程模型做一次深入理解.(注:本文的多处代码都并非原本的RxJava的源码,而是用来说明逻辑 ...

  5. 理解 RxJava 线程模型

    http://blog.saymagic.cn/2016/08/20/understand-rxjava-threading-model.html 主题 线程 RxJava RxJava作为目前一款超 ...

  6. 图扑孪生工厂流水线组态图可视化

    前言 2018 年,世界经济论坛(WEF)携手麦肯锡公司共同倡议并正式启动了全球"灯塔工厂网络项目"(Lighthouse Network),共同遴选率先应用工业革命 4.0 技术 ...

  7. 从工厂流水线到年薪20万程序员 | 深圳打工人的“跃龙门”

    故事的起点,大都从广东某条工厂流水线开始. 孙玲的故事,并非人人都听过.鼓舞他们踏出这一步的,是工友.同乡的起跳成功 . 进入IT业,被他们视为生命里至关重要的一次起跳.不是所有人,都能越过那道龙门. ...

  8. 如何让人大致理解RxJava思想:第一节 初步理解RxJava

    如何让人大致理解RxJava思想:第一节 初步理解RxJava 首先,我们需要明确,一个人不可能一口气吃成一个胖子,你不可能仅仅花5分钟看完我这篇文章,然后一拍桌子,大叫一声,我知道了,然后赢取白富美 ...

  9. 基于unet神经网络上采样中的的三种方式的理解

    关于前言 随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容中的一个知识点-上采样. 一.基于unet神经网络上采样中的的三种方式的理解 ...

最新文章

  1. 机器学习新手们 我这有本秘笈要不要?
  2. git File name too long
  3. PHP、jQuery、jQueryPager结合实现Ajax分页
  4. IDEA_Spring Data JPA有关报错Cannot resolve table 'XXX'
  5. SpringBoot_web开发-扩展与全面接管SpringMVC
  6. 省赛热身赛之Median
  7. Vue2.0 --- vue-cli脚手架中全局引入JQ
  8. QIcon 给按钮和动作添加图片
  9. 什么原因导致百度搜索比Google要少很多?
  10. 2、Python函数详解(0601)
  11. NumPy————NumPy广播机制的学习笔记
  12. Win11 22527.201更新补丁包下载
  13. react 中 Warning A future version of React will block javascript 异常解决
  14. css制作自动旋转的钟表
  15. 检查excel指定列中是否有错别字存在
  16. 不要相信深度学习报告的TOPS指标
  17. 婚宴座位图html5,结婚酒席座位安排
  18. word怎么打拼音声调的三种方法介绍
  19. CSS属性 – cursor
  20. matlab 数组显示图片,20.1.4 显示图像数据

热门文章

  1. SpringBoot购物推荐体育用品商城
  2. 基于SSM框架的体育用品商城购物系统
  3. 微信企业号多客服功能开发PHP
  4. 数据库 习题答案 系统概念 第8章
  5. 智能制造里ERP,MES和APS有什么区别和联系?
  6. ps神经网络滤镜安装包,ps神经网络滤镜用不了
  7. 【金融财经】金融市场一周简报(2017-12-08)
  8. ubuntu下载gmt_科学网—Ubuntu系统安装GMT - 陈超的博文
  9. 工作中常用的免费API,赶紧收藏起来~
  10. 在线重定义/*+ BYPASS_RECURSIVE_CHECK APPEND SKIP_UNQ_UNUSABLE_IDX */