鉴于 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. RPC框架研究(二)Hadoop源代码-1

    报名了阿里中间件性能大赛,我来说是一个全新的挑战.一切从空白学起,比赛的过程也是学习的过程 是的.想让自己学好.给自己报一个比赛吧~ 就像当初学围棋,也是报了围棋比赛,为了不至于输的太慘.一个星期里学 ...

  2. 使用Git下载Hadoop的到本地Eclipse开发环境

    使用Git下载Hadoop的到本地Eclipse开发环境 博客分类: Hadoop *n*x MacBook Air hadoopgitmaveneclipsejava  问题场景 按照官网http: ...

  3. PS中标尺工具在哪里

    打开photoshop应用程序,然后在PS菜单中点击“视图——标尺”选项即可打开ps标尺栏. 单位设置:      按Ctrl+K快捷键会弹出“首选项”对话框,你选择“单位与标尺”项,在“单位”一栏里 ...

  4. wepy - 与原生有什么不同(x.wpy)使用实例

    源码 <template> <view class='mark' wx:if="{{showMark}}"> <view animation=&quo ...

  5. Android OpenGL ES(四)----调整屏幕的宽高比

    1.宽高比问题 我们如今相当熟悉这样一个事实,在OpenGL里,我们要渲染的一切物体都要映射到X轴和Y轴上[-1,1]的范围内,对于Z轴也一样.这个范围内的坐标被称为归一化设备坐标,其独立于屏幕实际尺 ...

  6. HTTP协议详解之请求篇

    •HTTP请求由3部分组成:请求行.消息报头.请求正文. 1)请求行以一个方法符号开头,以空格分开,后面跟随请求的URI和协议的版本,格式:Method Request-URI HTTP-Versio ...

  7. Oracle的PLSQL别名中文出现乱码解决方法

     乱码之乱,乱在心里.行而上,眼迷茫! 01.查询oracle服务端默认语言 select * from nls_database_parameters NLS_LANGUAGE AMERICAN   ...

  8. LR杂记 - 性能測试指标及经常使用的监控工具

    监控指标 性能測试通常须要监控的指标包含: 1.serverLinux(包含CPU.Memory.Load.I/O). 2.数据库:1.Mysql 2.Oracle(缓存命中.索引.单条SQL性能.数 ...

  9. listView滚动事件

    listView滚动事件 实现接口: android.widget.AbsListView.OnScrollListener Interface definition for a callback t ...

  10. 使用Dockerfile文件构建基于centOS系统的tomcat镜像

    以下是Dockerfile的内容: #基础镜像 FROM centos #维护人员信息 MAINTAINER weigs "weigs1231@gmail.com" #设置工作目录 ...