声明
本系列文章是看书(RxJava 2.x 实战)后的记录,类似读书笔记,非原创
RxJava 的创建操作符主要包括如下内容:
- just():将一个或多个对象转换成发射这个或这些对象的一个 Observable
- from():将一个 Iterable、一个 Future 或者一个数组转换成一个 Observable
- create():使用一个函数从头创建一个 Observable
- defer():只有当订阅者订阅才创建 Observable,为每个订阅创建一个新的 Observable
- range():创建一个发射指定范围的整数序列的 Observable
- interval():创建一个按照给定的时间间隔发射整数序列的 Observable
- timer():创建一个在给定的延时之后发射单个数据的 Observable
- empty():创建一个什么都不做直接通知完成的 Observable
- error():创建一个什么都不做直接通知错误的 Observable
- never():创建一个不发射任何数据的 Observable
1. create、just 和 from
- create 使用一个从头开始创建一个 Observable,可以使用 create 操作符从头开始创建一个 Observable,给这个操作符传递一个接受观察者作为参数,编写这个函数让它的行为表现为一个 Observable——恰当地调用观察者的 onNext、onError 和 onComplete 方法。一个形式正确的有限 Observable 必须尝试调用观察者的 onComplete 或者 onError 一次,而且次后不能再调用观察者的任何其他方法。 RxJava 建议我们在传递给 create 方法的函数时,先检查一下观察者的 isDisposed 状态,以便在没有观察者的时候,让 Observable 停止发射数据,防止运行昂贵的运算。
Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
if (!emitter.isDisposed()) {
for (int i = 0; i < 10; i++) {
emitter.onNext(i);
}
emitter.onComplete();
}
}).subscribe(integer -> System.out.println("next: " + integer),
throwable -> System.out.println("error: " + throwable.getMessage()),
() -> System.out.println("Sequence complete."));
- just 创建一个发射指定值的 Observable,just 将单个数据转换为发射这个单个数据的 Observable。
Observable.just("hello just").subscribe(System.out::println);
just 类似 from,但是 from 回见数组或 Iterable 的数据取出然后逐个发射,而 just 只是简单的原样发射,将数组或 Iterable当做单个数据。它可以接受一至十个参数,返回一个按参数列表顺序发射这些数据的 Observable。 在 RxJava 2.0 中,如果在 just() 中传入 null,则会抛出一个空指针异常。
- from from 可以将其它种类的对象和数据类型转换为 Observable,当使用 Observable 时,如果要处理的数据都可以转换为 Observables,而不是需要混合使用 Observables 和其他类型的数据,会非常方便。 例如,Iterable 可以看成同步的 Observable;Future 可以看成总是只发射单个数据的 Observable。通过显式地将那些数据转换为 Observables,可以像使用 Observable 一样与它们交互。 在 RxJava 中,from 操作符可以将 Future、Iterable 和数组转换成 Observable。对于 Iterable 和数组,产生的 Observable 会发射 Iterable 或数组的每一项。 from 方法有一个可接受两个可选参数的版本,分别制定超时时长和时间单位。如果过了指定的时长,Future 还没有返回一个值,那么这个 Observable 就会发射错误通知并终止。
2. repeat
创建一个发射特定数据重复多次的 Observable,repeat 会重复地发射数据。某些实现允许重复发射某个数据序列,还有一些允许限制重复的次数。repeat 不是创建一个 Observable,而是重复发射原始 Observable 的数据序列,这个序列或许是无限的,或许是通过 repeat(n) 指定重复的次数。
Observable.just("hello world").repeat(3).subscribe(System.out::println);
在 RxJava 2.x 中还有两个跟 repeat 相关的操作符:repeatWhen 和 repeatUtil。
repeatWhen
repeatWhen 不是缓存和重放原始的 Observable 的数据序列,而是有条件地重新订阅和发射原来的 Observable。 将原始 Observable 的终止通知(完成或错误)当做一个 void 数据传递给一个通知处理器,以此来决定是否要重新订阅和发射原来的 Observable。这个通知处理器就像一个 Observable 操作符,接受一个发射 void 通知的 Observable 作为输入,返回一个发射 void 数据(重新订阅和发射 Observable) 或者直接终止(使用 repeatWhen 终止发射数据) 的 Observable。
Observable.range(0, 9).repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(Observable<Object> objectObservable) throws Exception {
return Observable.timer(10, TimeUnit.SECONDS);
}
}).subscribe(System.out::println);
try {
Thread.sleep(12000);
} catch (InterruptedException e) {
e.printStackTrace();
}
这里会发射 0~9 这几个数据,由于使用了 repeatWhen 操作符,因此在 10s 之后还会再发射一次这些数据。
repeatUntil
repeatUntil 是 RxJava 2.x 新增的操作符,表示直到某个条件就不再重复发射数据。当 BooleanSuppiler 的 getAsBoolean() 返回 false 时,表示重复发射上游的 Observable;当返回 true 时,表示中止重复发射上游的 Observable。
final long startTimeMillis = System.currentTimeMillis();
Observable.interval(500, TimeUnit.MILLISECONDS)
.take(5)
.repeatUntil(() -> {
System.out.println(System.currentTimeMillis() - startTimeMillis > 5000);
return System.currentTimeMillis() - startTimeMillis > 5000;
})
.subscribe(System.out::println);
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
3. defer、interval 和 timer
1. defer
直到有观察者订阅时才创建 Observable,并且为每个观察者创建一个全新的 Observable。defer 操作符会一直等待直到观察者订阅它,然后使用 Observable 工厂方法生成一个 Observable。对每个观察者都是这样做,因此尽管每个订阅者都以为自己订阅的是同一个 Observable,但实际上每个订阅者获取的是他们自己单独的数据序列。
Observable<String> observable = Observable.defer(new Callable<ObservableSource<? extends String>>() {
@Override
public ObservableSource<? extends String> call() throws Exception {
return Observable.just("hello world");
}
});
observable.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});
2. interval
创建一个按固定时间间隔发射整数序列的 Observable。interval 操作符返回一个 Observable,它按固定的时间间隔发射一个无线递增的整数序列。interval 接受一个表示时间间隔的参数和一个表示时间单位的参数。interval 默认在 computation 调度器上执行。
Observable.interval(1, TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
System.out.println(aLong);
}
});
3. timer
创建一个 Observable,在一个给定的延迟后发射一个特殊的值。timer 返回一个 Observable,在延迟一段时间后发射一个简单的数字 0。timer 操作符默认在 computation 调度上执行。
Observable.timer(2, TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
// 2 秒后打印
System.out.println("hello timer");
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
4. 小结
上述所有的创建操作符,不仅 Observable 可以使用,Flowable 等也可以使用。