鉴于 RxJava 眼下这样的既火爆又神奇的现状,而我又在一年的使用过程中对 RxJava 有了一些理解,我决定写下这篇文章来对 RxJava
做一个相对具体的、针对 Android 开发人员的介绍。

这篇文章的目的有两个:
1. 给对 RxJava 感兴趣的人一些入门的指引 2. 给正在使用 RxJava 但仍然心存疑惑的人一些更深入的解析。

在正文開始之前的最后,放上 GitHub 链接和引入依赖的 gradle 代码:
Github: 
https://github.com/ReactiveX/RxJava 
https://github.com/ReactiveX/RxAndroid 
引入依赖: 
compile 'io.reactivex:rxjava:1.0.14' 
compile 'io.reactivex:rxandroid:1.0.1' 

RxJava 究竟是什么

一个词:异步。

RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一个在 Java VM 上使用可观測的序列来组成异步的、基于事件的程序的库)。

这就是 RxJava ,概括得非常精准。

然而。对于刚開始学习的人来说。这太难看懂了。由于它是一个『总结』。而刚開始学习的人更须要一个『引言』。

事实上, RxJava 的本质能够压缩为异步这一个词。

说到根上,它就是一个实现异步操作的库,而别的定语都是基于这之上的。

RxJava 好在哪

换句话说,『相同是做异步,为什么人们用它,而不用现成的 AsyncTask / Handler / XXX / ... ?』

一个词:简洁。

异步操作非常关键的一点是程序的简洁性,由于在调度过程比較复杂的情况下,异步代码经常会既难写也难被读懂。 Android 创造的 AsyncTask 和Handler 。事实上都是为了让异步代码更加简洁。

RxJava
的优势也是简洁,但它的简洁的与众不同之处在于。随着程序逻辑变得越来越复杂。它依旧能够保持简洁。

假设有这样一个需求:界面上有一个自己定义的视图 imageCollectorView 。它的作用是显示多张图片。并能使用 addImage(Bitmap) 方法来随意添加显示的图片。

如今须要程序将一个给出的文件夹数组 File[]
folders
 中每一个文件夹下的 png 图片都载入出来并显示在imageCollectorView 中。须要注意的是。由于读取图片的这一过程较为耗时,须要放在后台运行,而图片的显示则必须在
UI 线程运行。

经常使用的实现方式有多种,我这里贴出当中一种:

而假设使用
RxJava ,实现方式是这样的:

那位说话了:『你这代码明明变多了啊。简洁个毛啊!』大兄弟你消消气,我说的是逻辑的简洁,不是单纯的代码量少(逻辑简洁才是提升读写代码速度的必杀技对不?)。观察一下你会发现, RxJava 的这个实现,是一条从上到下的链式调用。没有不论什么嵌套。这在逻辑的简洁性上是具有优势的。

当需求变得复杂时,这样的优势将更加明显(试想假设还要求仅仅选取前 10 张图片。常规方式要怎么办?假设有很多其它这样那样的要求呢?再试想,在这一大堆需求实现完两个月之后须要改功能,当你翻回这里看到自己当初写下的那一片迷之缩进,你能保证自己将迅速看懂,而不是对着代码又一次捋一遍思路?)。

另外,假设你的 IDE 是 Android Studio ,事实上每次打开某个 Java 文件的时候,你会看到被自己主动 Lambda 化的预览,这将让你更加清晰地看到程序逻辑:

假设你习惯使用 Retrolambda
,你也能够直接把代码写成上面这样的简洁的形式。而假设你看到这里还不知道什么是 Retrolambda ,我不建议你如今就去学习它。原因有两点:1. Lambda 是把双刃剑,它让你的代码简洁的同一时候,减少了代码的可读性,因此同一时候学习 RxJava 和 Retrolambda 可能会让你忽略 RxJava 的一些技术细节;2. Retrolambda 是 Java 6/7 对 Lambda 表达式的非官方兼容方案,它的向后兼容性和稳定性是无法保障的,因此对于企业项目,使用 Retrolambda 是有风险的。所以,与非常多
RxJava 的推广者不同。我并不推荐在学习 RxJava 的同一时候一起学习 Retrolambda。

事实上。我个人尽管非常赞赏 Retrolambda,但我从来不用它。

在Flipboard 的 Android 代码中,有一段逻辑非常复杂,包括了多次内存操作、本地文件操作和网络操作,对象分分合合,线程间相互配合相互等待,一会儿排成人字,一会儿排成一字。

假设使用常规的方法来实现,肯定是要写得欲仙欲死,然而在使用
RxJava 的情况下。依旧仅仅是一条链式调用就完毕了。

它非常长,但非常清晰。

所以, RxJava 好在哪?就好在简洁,好在那把什么复杂逻辑都能穿成一条线的简洁。

API 介绍和原理简析

这个我就做不到一个词说明了……由于这一节的主要内容就是一步步地说明 RxJava 究竟如何做到了异步。如何做到了简洁。

1. 概念:扩展的观察者模式

RxJava 的异步实现,是通过一种扩展的观察者模式来实现的。

观察者模式

先简述一下观察者模式,已经熟悉的能够跳过这一段。

观察者模式面向的需求是:A 对象(观察者)对 B 对象(被观察者)的某种变化高度敏感。须要在 B 变化的一瞬间做出反应。

举个样例,新闻里喜闻乐见的警察抓小偷,警察须要在小偷伸手作案的时候实施抓捕。在这个样例里。警察是观察者,小偷是被观察者,警察须要时刻盯着小偷的一举一动,才干保证不会漏过不论什么瞬间。程序的观察者模式和这样的真正的『观察』略有不同,观察者不须要时刻盯着被观察者(比如 A 不须要每过 2ms 就检查一次 B 的状态),而是採用注冊(Register)或者称为订阅(Subscribe)的方式,告诉被观察者:我须要你的某某状态,你要在它变化的时候通知我。
Android 开发中一个比較典型的样例是点击监听器OnClickListener 。

对设置 OnClickListener 来说。 View 是被观察者。 OnClickListener 是观察者。二者通过 setOnClickListener() 方法达成订阅关系。

订阅之后用户点击button的瞬间,Android
Framework 就会将点击事件发送给已经注冊的 OnClickListener 。採取这样被动的观察方式,既省去了重复检索状态的资源消耗。也能够得到最高的反馈速度。

当然。这也得益于我们能够随意定制自己程序中的观察者和被观察者。而警察叔叔明显无法要求小偷『你在作案的时候务必通知我』。

OnClickListener 的模式大致例如以下图:

如图所看到的,通过 setOnClickListener() 方法,Button 持有 OnClickListener 的引用(这一过程没有在图上画出)。当用户点击时,Button 自己主动调用 OnClickListener 的 onClick() 方法。另外,假设把这张图中的概念抽象出来(Button ->
被观察者、OnClickListener ->
观察者、setOnClickListener() ->
订阅,onClick() ->
事件),就由专用的观察者模式(比如仅仅用于监听控件点击)转变成了通用的观察者模式。例如以下图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGVuZ2FpYW56aHVv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

而 RxJava 作为一个工具库,使用的就是通用形式的观察者模式。

RxJava 的观察者模式

RxJava 有四个基本概念:Observable (可观察者,即被观察者)、 Observer (观察者)、subscribe (订阅)、事件。Observable 和 Observer 通过 subscribe() 方法实现订阅关系。从而 Observable 能够在须要的时候发出事件来通知 Observer

与传统观察者模式不同, RxJava 的事件回调方法除了普通事件 onNext() (相当于 onClick()onEvent())之外,还定义了两个特殊的事件:onCompleted() 和 onError()

  • onCompleted(): 事件队列完结。RxJava
    不仅把每一个事件单独处理,还会把它们看做一个队列。RxJava 规定,当不会再有新的 onNext() 发出时,须要触发 onCompleted() 方法作为标志。
  • onError(): 事件队列异常。在事件处理过程中出异常时,onError() 会被触发,同一时候队列自己主动终止。不同意再有事件发出。
  • 在一个正确运行的事件序列中, onCompleted() 和 onError() 有且仅仅有一个,而且是事件序列中的最后一个。须要注意的是,onCompleted() 和 onError() 二者也是相互排斥的,即在队列中调用了当中一个。就不应该再调用还有一个。

RxJava 的观察者模式大致例如以下图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGVuZ2FpYW56aHVv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

给 Android 开发人员的 RxJava 具体解释的更多相关文章

  1. 50个Android开发人员必备UI效果源码[转载]

    50个Android开发人员必备UI效果源码[转载] http://blog.csdn.net/qq1059458376/article/details/8145497 Android 仿微信之主页面 ...

  2. Android开发人员必知的开发资源

    developer.android.com 官方开发人员网站推荐资源 在动手编写第一个 Android 应用之前,用心读一读 Android Design 章节.尤其是以下的这些文章: Devices ...

  3. Android开发人员必须掌握的10 个开发工具+应该深入学习的10个开源应用项目

    一.Android开发人员必须掌握的10 个开发工具 Android SDK 本身包含很多帮助开发人员设计.开发.测试和发布 Android 应用的工具,在本文中,我们将讨论 10 个最常用的工具. ...

  4. Android 开发人员必须掌握的 10 个开发工具

    Android 开发人员必须掌握的 10 个开发工具 Android SDK 本身包含很多帮助开发人员设计.开发.测试和发布 Android 应用的工具,在本文中,我们将讨论 10 个最常用的工具. ...

  5. 为Android开发人员定制的搜索引擎

    我在谷歌上定制了一个专门针对Android开发人员的搜索引擎.载入慢的童鞋考虑FanQiang吧,作为技术人员使用Google才是王道. 在此推荐给大家:cx=01590883735180208228 ...

  6. 如何成为一个偷懒又高效的Android开发人员

    我敢肯定你对这个标题肯定心存疑惑,但事实就是如此,这个标题完全适合Android开发人员.据我所知, Android程序员不情愿写 findViewById().点击事件监听等重复率较高的代码.那我们 ...

  7. Android开发人员应该知道的Kotlin

    本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2016/01/kotlin-android Android开发人员在语言限制方面面临着 ...

  8. Android开发人员官方站点文档 - 国内踏得网镜像

    Android Developer 安卓开发人员官方站点无法正常訪问.即使FQ因为网络原因依旧訪问缓慢. 故整理相关字体.脚本.样式.页面资源,在踏得网server上建立了本地镜像.初始镜像时间201 ...

  9. Android开发人员必备的10个开发工具

    工欲善其事,必先利其器,Android SDK 本身包含很多帮助开发人员设计.开发.测试和发布 Android 应用的工具,在本文中,我们将讨论 10 个最常用的工具. 1.Eclipse ADT E ...

随机推荐

  1. Missing styles. Is the correct theme chosen for this layout? Use the Theme combo box above the layou

    android无法静态显示ui效果. Missing styles. Is the correct theme chosen for this layout? Use the Theme combo ...

  2. ZH奶酪:纯CSS自定义Html中Checkbox复选框样式

    原文链接:http://www.lrxin.com/archives-683.html 首先看下效果: 点击演示地址查看实例. 首先,需要添加一段CSS隐藏所有的Checkbox复选框,之后我们会改变 ...

  3. C# 编程实现串口通信

    http://blog.sina.com.cn/s/blog_6c67dab30101p3vn.html ----------------------------------------------- ...

  4. __inline定义的内联函数和宏的区别

    转自:http://blog.csdn.net/lw370481/article/details/7311668 函数与宏 #define TABLE_COMP(x) ((x)>0?(x):0) ...

  5. easyui问题小结

    http://blog.sina.com.cn/s/blog_77cb836301017lrd.html

  6. Sql_Handle and Plan_Handle Explained

    For batches, the SQL handles are hash values based on the SQL text. For database objects such as sto ...

  7. STS 自动生成 getter 和 setter

    1.Source --  Generate Getters and Setters

  8. JqGrid获得所有选中行数据ID数组,获取所有行的ID数组

    获得选中行的ID数组:var ids = $("jqgridtableid").jqGrid('getGridParam','selarrrow'); 获得所有行的ID数组:var ...

  9. 〖Windows〗zigbee实验之cygwin编译tinyos.jar编译出错的解决方法

    1. 使用的cygwin安装包下载地址:cygwin-files.zip 2. 使用的一些rpm安装包的下载地址:cygwin_cc2430_rpms.zip 3. cygwin的默认安装目录是:C: ...

  10. urlretrieve 如何给文件下载设置下载进度?

    #python #xiaodeng #如何给文件下载设置下载进度? import urllib def callbackinfo(down,block,size): ''' 回调函数: down:已经 ...