Rxjava2 介绍与详解实例

本文介绍了RxJava2的核心概念,包括ReactiveX历史、Observable的定义与优缺点,以及RxJava如何简化异步编程。详细讲解了RxJava中的Observer模式、Observable、Flowable、Single、Completable、Maybe和Subject等基础对象,并提供了实例代码。文章还提到了Scheduler在多线程中的应用,帮助读者理解RxJava的基础用法。
摘要由CSDN通过智能技术生成

前言

现在我们可以看到越来越多的开发者都在使用 Rx 相关的技术进行 App,Java 后端等领域进行开发。在开源的社区以及互联网公司,Rx、响应式编程、函数式都是热门的存在。所以笔者将结合自身的学习以及实际使用情况,写一个针对 Rxjava2 的系列文章,一起学习和使用 Rxjava 所带来的便捷。

笔者将利用工作之余,结合 ReactiveX 官方 Wiki 对 Rxjava 的定义与介绍,对相关基础知识、基本操作,常用部分的 API 进行整理,并加上个人理解和相关操作的示例。

相关参考链接:

Rxjava2 系列文章目录:

实例代码:

RX介绍

ReactiveX的历史

ReactiveX 是Reactive Extensions的缩写,一般简写为Rx,最初是LINQ的一个扩展,由微软的架构师Erik Meijer领导的团队开发,在2012年11月开源,Rx是一个编程模型,目标是提供一致的编程接口,帮助开发者更方便的处理异步数据流,Rx库支持.NET、JavaScript和C++,Rx近几年越来越流行了,现在已经支持几乎全部的流行编程语言了,Rx的大部分语言库由ReactiveX这个组织负责维护,比较流行的有RxJava/RxJS/Rx.NET,社区网站是reactivex.io。

什么是ReactiveX

微软给的定义是,Rx是一个函数库,让开发者可以利用可观察序列和LINQ风格查询操作符来编写异步和基于事件的程序,使用Rx,开发者可以用Observables表示异步数据流,用LINQ操作符查询异步数据流, 用Schedulers参数化异步数据流的并发处理,Rx可以这样定义:Rx = Observables + LINQ + Schedulers。

ReactiveX.io给的定义是,Rx是一个使用可观察数据流进行异步编程的编程接口,ReactiveX结合了观察者模式迭代器模式函数式编程的精华。

RxJava 到底是什么

RxJava 在 GitHub 主页上的自我介绍是 “a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)。这就是 RxJava ,概括得非常精准。

然而,对于初学者来说,这还是比较含蓄难懂的。因为它是一个总结,而初学者更需要一个入门的介绍或者理解。其实, RxJava 的本质可以总结为异步的概念。说到本质上,它就是一个实现异步操作的库。RxJava 的异步实现,是通过一种扩展的观察者模式来实现的。

RxJava 优点

同样是做异步,为什么去使用它,而不用现成的 Thread,ThreadPoolExecutor,Android的AsyncTask / Handler / … ?其实就是简洁,易用 !

异步操作很关键的一点是程序的简洁性,因为在调度过程比较复杂的情况下,异步代码经常会既难写也难被读懂。 正如Android 创造的 AsyncTask 和Handler ,其实都是为了让异步代码更加简洁。RxJava 的优势也是简洁,但它的简洁的与众不同之处在于,随着程序逻辑变得越来越复杂,它依然能够保持简洁

名词定义

  • Reactive 直译为反应性的,有活性的,根据上下文一般翻译为反应式、响应式。
  • Iterable 可迭代对象,支持以迭代器的形式遍历,许多语言中都存在这个概念。
  • Observable 可观察对象,在Rx中定义为更强大的Iterable,在观察者模式中是被观察的对象,一旦数据产生或发生变化,会通过某种方式通知观察者或订阅者。
  • Observer 观察者对象,监听Observable发射的数据并做出响应,Subscriber是它的一个特殊实现。
  • emit 直译为发射,发布,发出,含义是Observable在数据产生或变化时发送通知给Observer,调用Observer对应的方法,文章里一律译为发射。
  • items 直译为项目,条目,在Rx里是指Observable发射的数据项,文章里一律译为数据,数据项。

Rx模式

使用观察者模式

  • 创建:Rx可以方便的创建事件流和数据流
  • 组合:Rx使用查询式的操作符组合和变换数据流
  • 监听:Rx可以订阅任何可观察的数据流并执行操作

简化代码

  • 函数式风格:对可观察数据流使用无副作用的输入输出函数,避免了程序里错综复杂的状态
  • 简化代码:Rx的操作符通通常可以将复杂的难题简化为很少的几行代码
  • 异步错误处理:传统的try/catch没办法处理异步计算,Rx提供了合适的错误处理机制
  • 轻松使用并发:Rx的Observables和Schedulers让开发者可以摆脱底层的线程同步和各种
    并发问题

使用Observable的优势

Rx扩展了观察者模式用于支持数据和事件序列,添加了一些操作符,它让你可以声明式的组合这些序列,而无需关注底层的实现:如线程、同步、线程安全、并发数据结构和非阻塞IO。

Observable通过使用最佳的方式访问异步数据序列填补了这个间隙。

类型 单个数据 多个数据
同步 T getData() Iterable getData
异步 Future<T> getData() Observable<T> getData()

Rx的Observable模型让你可以像使用集合数据一样操作异步事件流,对异步事件流使用各种
简单、可组合的操作。

1. Observable可组合

对于单层的异步操作来说,Java中Future对象的处理方式是非常简单有效的,但是一旦涉及到嵌套,它们就开始变得异常繁琐和复杂。使用Future很难很好的组合带条件的异步执行流程(考虑到运行时各种潜在的问题,甚至可以说是不可能的),当然,要想实现还是可以做到的,但是非常困难,或许你可以用 Future.get() ,但这样做,异步执行的优势就完全没有了。从另一方面说,Rx的bservable一开始就是为组合异步数据流准备的。

2. Observable更灵活

Rx的Observable不仅支持处理单独的标量值(就像Future可以做的),也支持数据序列,甚至是无穷的数据流。 Observable 是一个抽象概念,适用于任何场景。Observable拥有它的近亲Iterable的全部优雅与灵活。

Observable是异步的双向push,Iterable是同步的单向pull,对比:

事件 Iterable(pull) Observable(push)
获取数据 T next() onNext(T)
异常处理 throws Exception onError(Exception)
任务完成 !hasNext() onCompleted

3. Observable无偏见

Rx对于对于并发性或异步性没有任何特殊的偏好,Observable可以用任何方式实现,线程池、事件循环、非阻塞IO、Actor模式,任何满足你的需求的,你擅长或偏好的方式都可以。无论你选择怎样实现它,无论底层实现是阻塞的还是非阻塞的,客户端代码将所有与Observable的交互都当做是异步的。

Rx使用依赖:

下列是笔者使用的版本(可根据实际情况进行选择):

  1. 使用Gradle依赖:implementation "io.reactivex.rxjava2:rxjava:2.2.12"
  2. 使用Maven依赖或者Jar包下载 :Rxjava 2.2.12
  3. 其他版本以及相关下载 :Maven

Rxjava的入门基础

1. Observable

1.1 观察者模式

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

在RxJava中,一个实现了 Observer 接口的对象可以订阅 (subscribe) 一个 Observable 类的实例。订阅者(subscriber) 对 Observable 发射 (emit) 的任何数据或数据序列作出响应。这种模式 简化了并发操作,因为它不需要阻塞等待 Observable 发射数据,而是创建了一个处于待命状态的观察者哨兵,哨兵在未来某个时刻响应Observable的通知。

RxJava 的事件回调方法: onSubscribe()onNext()onCompleted()onError()

  • onSubscribe(): 当被观察者被观察者订阅的时候触发。
  • onNext(): 当被观察者发送数据的时候通过此方法通知观察者数据变换。
  • onCompleted(): 事件队列完结。RxJava 不仅把每个事件单独处理,还会把它们看做一个队列。RxJava 规定,当不会再有新的 onNext() 发出时,需要触发 onCompleted() 方法作为标志。
  • onError(): 事件队列异常。在事件处理过程中出异常时,onError() 会被触发,同时队列自动终止,不允许再有事件发出。

注意: 在一个正确运行的事件序列中, onCompleted() 和 onError() 有且只有一个,并且是事件序列中的最后一个。需要注意的是,onCompleted() 和 onError() 二者也是互斥的,即在队列中调用了其中一个,就不应该再调用另一个。

1.2 Consumer 和 Action

这两个词意思分别是 消费者(可以理解为消费被观察者发射出来的事件)和 行为(可以理解为响应被观察者的行为)。对于 Observer 中的 4 个回调方法,我们未必都能用得到,如果只需要用到其中的一部分,就需要 Consumer 和 Action 上场了。

简单示例:

	// 1. 进行订阅,subscribe(Observer)
	observable.subscribe(observer);
		
	System.out.println("---------------------------------------------");
	// 2. 进行订阅,subscribe(Consumer onNext)
	observable.subscribe(nextConsumer);
	
	System.out.println("---------------------------------------------");
	// 3. 进行订阅,subscribe(Consumer onNext, Consumer onError)
	observable.subscribe(nextConsumer, errorConsumer);
		
	System.out.println("---------------------------------------------");
	// 4. 进行订阅,subscribe(Consumer onNext, Consumer onError, Action onCompleted)
	observable.subscribe(nextConsumer, errorConsumer, completedAction);
		
	System.out.println("---------------------------------------------");
	// 5. 进行订阅,subscribe(Consumer onNext, Consumer onError, Action onCompleted, Consumer onSubscribe)
	observable.subscribe(nextConsumer, errorConsumer, completedAction, onSubscribeComsumer);

1.3 Observable的分类

在RxJava中,Observable 有 Hot 与 Cold 之分。

  • Hot Observable : 无论有没有观察者进行订阅,事件始终都会发生。当有多个观察者订阅时,Hot Observable此时与订阅者们的关系时一对多的关系,可以与多个订阅者共享信息。
  • Cold Observable : 只有有观察者订阅了,才开始执行数据流的发送,并且与观察者时一对一的关系。当有多个不同的订阅者时,消息是重新完整发送的,也就是说对于订阅者们来说,它们的事件是彼此独立的。

Javadoc: Observable

2. Flowable

Rxjava2.x 中有这么一个被观察者 Flowable,同样作为被观察者,它和Observable有什么区别呢,在Rxjava2中,Observable不再支持背压,而新增的Flowable支持背压,何为背压,就是异步场景下上游发送事件的速度大于下游处理事件的速度所产生的现象。

img-Flowable

提示:在本系列后面会有详细的单独篇章来介绍和如何使用背压。
Javadoc: Flowable

3. Single

Single 类似于 Observable,不同的是,它总是只发射一个值,或者一个错误通知,而不是发射一系列的值。

因此,不同于Observable需要三个方法 onNext, onError, onCompleted,订阅Single只需要两个方法:

  • onSuccess: Single发射单个的值到这个方法
  • onError: 如果无法发射需要的值,Single发射一个Throwable对象到这个方法

Single 只会调用这两个方法中的一个,而且只会调用一次,调用了任何一个方法之后,订阅关系终止。

img-single

示例代码:

	// Single: 只发送 onSuccess or onError 通知,并且只会发送一次, 第一次发送数据后的都不会在处理
	Single.create(new SingleOnSubscribe<String>() {
   
	
			@Override
			public void subscribe(SingleEmitter<String> emitter) throws Exception {
   
				emitter.onSuccess("Success");			// 发送success通知
				emitter.onSuccess("Success2");		// 只能发送一次通知,后续不在处理
			}
	}).subscribe(new BiConsumer<String, Throwable>() {
   
	
			@Override
			public void accept(String t1, Throwable t2) throws Exception {
   
				System.out.println("--> accept: t1 = " + t1 + ",  t2 = " + t2);
			}
	});

输出:

--> accept: t1 = Success,  t2 = null

提示:Single 可以通过 toXXX 方法转换为 Observable, Flowable, Completable与Maybe。
Javadoc: Single

4. Completable

Completable 在创建后,不会发射任何数据, 只有 onCompleteonError事件,同时没有Observable中的一些操作符,如 map,flatMap。通常与 andThen 操作符结合使用。

img-Completable

示例代码:

	// 1. Completable:只发送complete 或 error 事件,不发送任何数据
	Completable.fromAction(new Action() {
   

		@Override
		public void run() throws Exception {
   
			System.out.println("Hello World! This is Completable.");
		}
	}).subscribe(new CompletableObserver() {
   

		@Override
		public void onSubscribe(Disposable d) {
   
			System.out.println("--> onSubscribe");
		}

		@Override
		public void onError(Throwable e) {
   
			System.out.println("--> onError");
		}

		@Override
		public void 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值