2. RxJava1.x基本概念

来源:互联网 发布:植物人复苏 知乎 编辑:程序博客网 时间:2024/05/16 00:25

欢迎大家加入QQ群一起讨论: 489873144(android格调小窝)
我的github地址:https://github.com/jeasonlzy

RxJava源码导入

我们在下rxjava的源码后,直接把src/main/java下的代码复制到我们的工程中,这时会出现一个类找不到

import sun.misc.Unsafe;

我们需要将以下图片的位置改为warning级别,就可以正常编译运行了。

1. 概念

Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)

rxjava的官方网站
rxjava的github
rxjava的wiki
抛物线的经典文章:给 Android 开发者的 RxJava 详解

一个数据流是一个按时间排序的即将发生的事件的序列。它可以发出3种不同的事件:一个某种类型的值事件,一个错误事件和一个完成事件。但是我们只能异步捕捉被发出的事件,使得我们可以在发出一个值事件时执行一个函数,发出错误事件时执行一个函数,发出完成事件时执行另一个函数。有时候可以忽略后两个事件,只需聚焦于如何定义和设计在发出值事件时要执行的函数,监听这个事件流的过程叫做订阅,我们定义的函数叫做观察者,而事件流就可以叫做被观察的主题(或者叫被观察者),这就是观察者模式。

RxJava是基于观察者模式的:
- 如果一个Observerble没有任何的的Subscriber,那么这个Observable是不会发出任何事件的。
- 生产者在没有更多数据可用时能够发出信号通知:onCompleted()事件。
- 生产者在发生错误时能够发出信号通知:onError()事件。
- RxJava Observables能够组合而不是嵌套,从而避免升发者陷入回调地狱。

这篇文章是基于RxJava 1.2.6版本的。在这个版本中,有以下几个基本概念

2. Observable / Single

可观测序列(Observable)是对数据源的一次包装,让一个普通数据源,变成一个可观测序列,可以将事件发送到观察者。

可观测序列就像一条河,它们是流动的。你可以”过滤”(filter)一条河,你可以”转换”(transform)一条河,你可以将两条河”合并”(combine)成一个,然后依然畅流如初。最后,它就成了你想要的那条河。这就是数据流。

从发射物的角度来看,有两种不同的Observables:Hot和Cold的。一个Hot Observable只要一创建完就升始发射数据,因此所有后续订阅它的观察者可能从序列中间的某个位置开始接受数据(有一些数据错过了就接受不到了)。一个Cold Observable会一直等待,直到有观察者订阅它才升始发射数据,因此这个观察者可以确保会收到整个数据序列。

Single类似于Observable,不同的是,它总是只发射一个值,或者一个错误通知,而不是发射一系列的值。因此,不同于Observable需要三个方法onNext, onError, onCompleted,订阅Single只需要两个方法:
- onSuccess - Single发射单个的值到这个方法
- onError - 如果无法发射需要的值,Single发射一个Throwable对象到这个方法

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

3. Observer / Subcriber

观察者(Observer)/订阅者(Subcriber):观察事件并处理事件的对象,用于接受到发送的事件时,对事件进行处理的。它决定事件触发的时候将有怎样的行为,其中Subscriber是对Observer 接口进行的一些扩展,它有一个unsubscribe方法。调用这个方法表示你不关心当前订阅的Observable了,因此Observable可以选择停止发射新的数据项(如果没有其它观察者订阅),其余的基本使用方式是完全一样的,


注意以下几点:
1. 在发射任何数据(或者通知)给订阅者之前,你的序列操作符可能需要检查它的 Subscriber.isUnsubscribed() 状态,如果没有订阅者了,没必要浪费时间生成数据项。
2. 序列操作符必须复合Observable协议的核心原则:
- 它可能调用订阅者的 onNext() 方法任意次,但是这些调用必须是不重叠的。
- 它只能调用订阅者的 onCompleted() 或 onError() 正好一次,但不能都调用,而且不能在这之后调用订阅者的 onNext() 方法。
3. 如果你不能保证你得操作符遵从这两个原则,你可以给它添加 serialize() 操作符,它会强制保持正确的行为。
4. 不要让你的操作符阻塞别的操作。
5. 如果可能,你应该组合现有的操作符创建你的新操作符,而不是从零开始实现它。RxJava自身的标准操作符也是这样做的,例如:
- first() 被定义为 take(1).single()
- ignoreElements() 被定义为 filter(alwaysFalse())
- reduce(a) 被定义为 scan(a).last()
6. 一般说来,一旦发生错误应立即通知订阅者,而不是首先尝试发射更多的数据。
7. null 可能是Observable发射的一个合法数据。一个值为null的数据仍然是一个发射数据项,它与没有发射任何东西是不能等同的。

4. subscribe

Observable与Observer连接的纽带,产生订阅关系,开始发送数据,通常使用以下方法关联Observable与Observer

Observable.subscribe(Observer)或者Observable.subscribe(Subcriber)

除了上面的调用方法以外,还支持三个不完整回调,如下:

Observable.subscribe(Action1<T> onNext);Observable.subscribe(Action1<T> onNext, Action1<Throwable> onError);Observable.subscribe(Action1<T> onNext, Action1<Throwable> onError, Action0 onCompleted);

什么叫不完整回调呢?名字很高大上,说白了就是本来Observer回调应该有三个方法,可是其余的两个方法我不常用,可以不可以省略不写?当然可以,那么你就传一个和你需要的那个方法的签名一模一样的就行了,其实在源码的内部,依然是给你传了两个默认的方法,不信你看:

5. Subject = Observable + Observer

subject是一个神奇的对象,它可以是一个Observable同时也可以是一个Observer:它作为连接这两个世界的一座桥梁。一个Subject可以订阅一个Observable,就像一个观察者,并且它可以发射新的数据,或者传递它接受到的数据,就像一个Observable。很明显,作为一个Observable,观察者们或者其它Subject都可以订阅它。一旦Subject订阅了Observable,它将会触发Observable升始发射。如果原始的Observable是”冷”的,这将会对订阅一个”热”的Observable变量产生影响。

下图是他的定义:继承至Observable又实现了Observer。

RxJava提供四手中不同的Subject:

  • PublishSubject
  • BehaviorSubject
  • ReplaySubject
  • AsyncSubject

5.1 PublishSubject

我们用create()方法创建一个PublishSubject,然后我们订阅了PublishSubject。此时,没有数据要发送,因此我们的观察者只能等待,没有阻塞线程,也没有消耗资源。就在这随时准备从subject接收值,如果subject没有发射值那么我们的观察者就会一直在等待。我们并不关心它什么时候响应。我们只关心它响应时该做什么。最后subject发射了数据hello,那么观察者最后将接受到事件hello。

再看一个例子

最后的结果将会打印:

System.out: First onNext value : 1System.out: First onNext value : 2System.out: First onNext value : 3System.out: First onNext value : 4System.out: Second onNext value : 4System.out: First onCompletedSystem.out: Second onCompleted

5.2 BehaviorSubject

简单的说,BehaviorSubject会首先向他的订阅者发送截至订阅前最新的一个数据对象(或初始值),然后正常发送订阅后的数据流。

结果如下:

System.out: First onNext value : 1System.out: First onNext value : 2System.out: First onNext value : 3System.out: Second onNext value : 3System.out: First onNext value : 4System.out: Second onNext value : 4System.out: First onCompletedSystem.out: Second onCompleted

5.3 ReplaySubject

ReplaySubject会缓存它所订阅的所有数据,向任意一个订阅它的观察者重发

结果如下:

System.out: First onNext value : 1System.out: First onNext value : 2System.out: First onNext value : 3System.out: First onNext value : 4System.out: First onCompletedSystem.out: Second onNext value : 1System.out: Second onNext value : 2System.out: Second onNext value : 3System.out: Second onNext value : 4System.out: Second onCompleted

5.4 AsyncSubject

当Observable完成时AsyncSubject只会发布最后一个数据给已经订阅的每一个观察者。

结果如下:

System.out: First onNext value : 4System.out: First onCompletedSystem.out: Second onNext value : 4System.out: Second onCompleted

如果你觉得好,对你有过帮助,请给我一点打赏鼓励吧,一分也是爱呀!

原创粉丝点击