1. 函数晌应式编程的概念
如果你曾经使用过 Java ,那么你 定听说过面向对象(OOP)的编程思想,也可能听说过 AOP ( Aspect Orient Programming ,面向切面编程)的编程思想。
1.1 响应式编程( Reactive Programming ,简称 RP )
在计算机中,响应式编程是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。
传统的编程方式是顺序执行的,需要等待直至完成上一个任务之后才会执行下一个任务。无论是提升机器的性能还是代码的性能,本质上都需要依赖上一个任务的完成。如果需要响应迅速,就得把同步执行的方式换成异步执行,方法执行变成消息发送。这就是异步编程的方式,它是响应式编程的重要特性之一。
响应式编程有以下几个特点:
- 异步编程:提供了合适的异步编程模型,能够挖掘多核 CPU 的能力、提高效率、降低延迟和阻塞等。
- 数据流:基于数据流模型,响应式编程提供一套统一的 Stream 风格的数据处理接口。与 Java 中的 Stream 相比,响应式编程除了支持静态数据流,还支持动态数据流,并且允许复用和同时接入多个订阅者。
- 变化传播:简单来说就是以一个数据流为输入,经过一连串操作转化为另一个数据流,然后分发给各个订阅者的过程。这就有点像函数式编程中的组合函数,将多个函数串联起来,把一组输入数据转化为格式迥异的输出数据。
现在的 App 无论是原生 H5, HTML5 还是 Hybird ,都会和与数据事件相关的 UI 事件进行大量的交互,使用响应式编程会显得更加得心应手。
1.2 函数式编程( Functional Programming ,简称 FP)
随着硬件能力的不断提升,单核 CPU 计算能力几乎达到极限, CPU 己经进入了多核时代,程序员转而通过并发编程、分布式系统来应对越来越复杂的计算任务。
然而井发编程是基于内存共享,多线程编程有常见的死锁、线程饥饿、竞争条件等问题,而且多线程的 Bug 也难以重现和定位。
在函数式编程中,由于数据是不可变的 immutable ),因此没有并发编程的问题,是线程安全的。它将计算机运算看作数学中函数的计算,主要特点是将计算过程分解成多个可复用的函数,并且避免了状态及变量的概念。
1.3 函数响应式编程( Functional Reactive Programming ,简称 FRP)
函数响应式编程结合了函数式和响应式的优点,把函数范式里的一套思路和响应式编程合起来就是函数响应式编程。
我们知道,传统的面向对象编程是通过抽象出的对象关系来解决问题,函数式编程是通过函数(function)的组合来解决问题,响应式编程是通过函数式编程的方式来解决回调地狱(Callback Hell) 的问题。
用传统的面向对象来处理异步事件不是很直观,处理并发也十分麻烦,所以才产生了函数响应式编程。
2. RxJava 简介
2.1 RxJava 产生的由来
RxJava是Reactive Extensions Java 实现,用于通过使用 Observable/Flowable 序列来构建异步和基于事件的程序的库。
RxJava 扩展观察者模式以支持数据/事件序列,并添加允许你以声明方式组合序列的操作符,同时提取对低优先级的线程、同步、线程安全性和并发数据结构等问题的隐藏。
2.2 什么是 Rx
ReactiveX 是 Reactive Extensions 的缩写, 般简写为Rx,最初是 LINQ 个扩展,由微软架构师Erik.Meijer 领导的团队所开发,于 2012年11月开源。 Rx是一个编程模型,目标是提供一致的编程接口,帮助开发者更方便地处理异步数据流。Rx 库支持 .NET、JavaScript和C++。由于 Rx 近几年越来越流行,因此现在己经支持几乎全部的流行编程语言。 Rx的大部分语言库由 ReactiveX 这个组织负责维护,比较流行的有 RxJava RxJS Rx.NET ,社区网站是http://reactivex.io
2.3 ReactiveX 的历史
微软给的定义是, Rx是一个函数库,让开发者可以利用可观察序列和 LINQ 风格查询操作符来编写异步和基于事件的程序,通过使用Rx, 开发者可以用 Observables 表示异步数据流,用 LINQ 操作符查询异步数据流,用 Schedulers 参数化异步数据流的并发处理。可以这样定义
Rx: Rx= Observables + LINQ + Schedulers
注:在 RxJava 2.x 中, Observables 包含了 Observables、Flowable、Single、Maybe、Completable等
ReactiveX.io 给的定义是, Rx是一个使用可观察数据流进行异步编程的编程接口,ReactiveX 结合了观察者模式、 迭代器模式和函数式编程的精华。
2.4 Rx 模式
(1) 使用观察者模式
- 创建: Rx 可以方便地创建事件流和数据流
- 组合: Rx 使用查询式的操作符组合和变换数据流
- 监听: Rx 可以订阅任何可观察的数据流并执行操作
(2) 简化代码
- 函数式风格: 对可观察的数据流使用无副作用的输入/输出函数,避免了程序里错综复
杂的状态
- 简化代码: Rx 操作符通常可以将复杂的难题简化为很少的几行代码
- 异步错误处理: 传统的 try/catch 没办法处理异步计算, Rx 提供了合适的错误处理机制
- 轻松使用井发: Rx的Observables (包括 Observable、Flowable、Single、Completable和Maybe )和 Schedulers 可以让开发者摆脱底层的线程同步和各种并发问题
3. 为何选择 RxJava
Rx 扩展了观察者模式用于支持数据和事件序列,添加了一些操作符,让你可以使用声明式的方式来组合这些序列,而无须关注底层的实现,如线程、同步、线程安全、并发数据结构和非阻塞I/OI
Rx的Observable 模型让开发者可以像使用集合数据一样操作异步事件流,对异步事件流使用各种简单、可组合的操作。
- 可组合
对于单层的异步操作来说,Java中的Future 对象的处理方式非常简单有效,但是一旦涉及嵌套,它们就开始变得异常烦琐和复杂。 在Java 8 之前,使用 Future 很难很好地组合带条件的异步执行流程。从另一方面来说, RxJava 的被观察者们(Observable/Flowable/Single/Completable/May)一开始就是为组合异步数据流准备的。
- 更灵活
RxJava 的 Observable 不仅支持处理单独的标量值(就像 Future 可以做的〉,还支持数据序
列,甚至是无穷的数据流,Observable 个抽象概念,适用于任何场景。 Observable 拥有它的Iterable的全部优雅与灵活
- 无偏见
Rx 对于井发性或异步性没有任何特殊的偏好, Observable 可以用任何方式(如线程池、事件循环、非阻塞I/O、 Actor 模式)来满足我们的需求。 无论我们选择怎样实现它,无论底层实现是阻塞的还是非阻塞的,客户端代码都将与 Observable 的全部交互当成是异步的。
4. RxJava 能做什么
在 Android 开发中哪些地方可以使用 RxJava ?任何地方,包括 App 所依赖的底层框架。
例如,可以使用 RxBinding ,它是对 Android View 事件的扩展,可以对 View 事件使用 RxJava
的各种操作。
对于 Android 的 AsyncTask ,也可以完全使用 RxJava 来替代。
5. RxJava 2 的 Hello World
RxJava 版本的 Hello World
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("Hello World!");
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, "accept: " + s);
}
});
这个写法比较长,可以简单一点的写法
Observable.just("Hello World!").subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, "accept: " + s);
}
});
还可以借助 Lambda 表达式再简化
Observable.just("Hello World!").subscribe(System.out::println);
目前在移动端可以看到大量使用 RxJava 来编写的代码,也因此产生了大量的优秀框架,比如 RxBinding Retrofit RxLifecycle 等
如果我的文章对您有帮助,不妨点个赞鼓励一下(^_^)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。