在现代的软件开发领域,响应式编程正逐渐成为一种主流的编程范式。它能够以一种简洁、高效且灵活的方式处理异步数据流,尤其适用于处理复杂的异步操作和事件驱动的场景。RxJava 作为 Java 平台上响应式编程的优秀实现,为开发者提供了丰富的操作符和工具,极大地简化了异步编程的复杂度。
本博客将深入探讨 RxJava 基础核心操作模块的使用原理,通过对源码的详细分析,帮助读者理解 RxJava 是如何实现各种操作符的,以及这些操作符背后的设计思想和工作机制。我们将从最基本的概念入手,逐步深入到每个核心操作模块的内部实现,让读者对 RxJava 有一个全面而深入的认识。
响应式编程是一种面向数据流和变化传播的编程范式。它的核心思想是将数据的变化看作是一种流,通过对这些流进行操作和转换,实现数据的处理和响应。在响应式编程中,数据的变化会自动触发相应的操作,从而实现高效的异步处理和事件驱动。
例如,在一个图形用户界面(GUI)应用中,用户的鼠标点击、键盘输入等事件都可以看作是数据流。通过响应式编程,我们可以将这些事件流进行处理和转换,实现界面的交互和更新。
Observable
对象可以发出零个或多个数据项,并且可以在数据发送完成后发出一个完成信号或者一个错误信号。import io.reactivex.Observable;
// 创建一个 Observable 对象,发出三个整数数据
Observable<Integer> observable = Observable.just(1, 2, 3);
在上述代码中,Observable.just(1, 2, 3)
创建了一个 Observable
对象,它会依次发出整数 1、2 和 3。
Observable
发出的数据。一个 Observer
对象需要实现 onNext()
、onError()
和 onComplete()
三个方法,分别用于处理接收到的数据、处理错误和处理完成信号。import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
// 创建一个 Observer 对象
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
// 当观察者订阅 Observable 时调用
System.out.println("onSubscribe");
}
@Override
public void onNext(Integer value) {
// 当接收到 Observable 发出的数据时调用
System.out.println("onNext: " + value);
}
@Override
public void onError(Throwable e) {
// 当 Observable 发出错误信号时调用
System.out.println("onError: " + e.getMessage());
}
@Override
public void onComplete() {
// 当 Observable 发出完成信号时调用
System.out.println("onComplete");
}
};
在上述代码中,我们创建了一个 Observer
对象,并重写了 onSubscribe()
、onNext()
、onError()
和 onComplete()
方法。
subscribe()
方法可以将 Observable
和 Observer
建立订阅关系,从而使 Observer
能够接收到 Observable
发出的数据。// 建立 Observable 和 Observer 的订阅关系
observable.subscribe(observer);
在上述代码中,observable.subscribe(observer)
建立了 observable
和 observer
的订阅关系,observer
会开始接收 observable
发出的数据。
Disposable
是一个用于管理订阅关系的接口,它提供了 dispose()
方法用于取消订阅。当调用 dispose()
方法后,Observer
将不再接收 Observable
发出的数据。
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
// 创建一个 Observable 对象
Observable<Integer> observable = Observable.just(1, 2, 3);
// 创建一个 Observer 对象
Observer<Integer> observer = new Observer<Integer>() {
private Disposable disposable;
@Override
public void onSubscribe(Disposable d) {
this.disposable = d;
// 可以在这里决定是否取消订阅
// disposable.dispose();
}
@Override
public void onNext(Integer value) {
if (value == 2) {
// 当接收到数据 2 时,取消订阅
disposable.dispose();
}
System.out.println("onNext: " + value);
}
@Override
public void onError(Throwable e) {
System.out.println("onError: " + e.getMessage());
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
};
// 建立订阅关系
observable.subscribe(observer);
在上述代码中,我们在 onSubscribe()
方法中保存了 Disposable
对象,并在 onNext()
方法中根据条件取消了订阅。
Scheduler
是 RxJava 中用于控制线程调度的工具。它可以指定 Observable
发出数据的线程和 Observer
接收数据的线程。RxJava 提供了多种内置的 Scheduler
,如 Schedulers.io()
用于 I/O 操作、Schedulers.computation()
用于计算密集型操作等。
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
// 创建一个 Observable 对象
Observable<Integer> observable = Observable.just(1, 2, 3);
// 指定 Observable 发出数据的线程为 I/O 线程
observable.subscribeOn(Schedulers.io())
// 指定 Observer 接收数据的线程为计算线程
.observeOn(Schedulers.computation())
.subscribe(System.out::println);
在上述代码中,subscribeOn(Schedulers.io())
指定了 Observable
发出数据的线程为 I/O 线程,observeOn(Schedulers.computation())
指定了 Observer
接收数据的线程为计算线程。
create()
操作符是最基本的创建 Observable
的方法,它允许开发者手动控制 Observable
的数据发射过程。通过 ObservableOnSubscribe
接口,我们可以定义 Observable
如何发出数据、错误和完成信号。
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
// 创建一个 Observable 对象,使用 create() 操作符
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
// 发出数据 1
emitter.onNext(1);
// 发出数据 2
emitter.onNext(2);
// 发出数据 3
emitter.onNext(3);
// 发出完成信号
emitter.onComplete();
}
});
// 创建一个 Observer 对象
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("onSubscribe");
}
@Override
public void onNext(Integer value) {
System.out.println("onNext: " + value);
}
@Override
public void onError(Throwable e) {
System.out.println("onError: " + e.getMessage());
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
};
// 建立订阅关系
observable.subscribe(observer);
在上述代码中,我们使用 create()
操作符创建了一个 Observable
对象,并在 subscribe()
方法中手动控制数据的发射。
create()
方法的源码如下:
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
// 检查 source 是否为 null
ObjectHelper.requireNonNull(source, "source is null");
// 创建一个 ObservableCreate 对象,将 source 作为参数传入
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
在上述代码中,create()
方法首先检查传入的 ObservableOnSubscribe
对象是否为 null
,然后创建了一个 ObservableCreate
对象,并将 source
作为参数传入。最后,调用 RxJavaPlugins.onAssembly()
方法对 ObservableCreate
对象进行一些全局的组装操作。
ObservableCreate
类的源码如下:
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
// 保存传入的 ObservableOnSubscribe 对象
this.source = source;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
// 创建一个 CreateEmitter 对象,用于发射数据
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
// 调用观察者的 onSubscribe() 方法
observer.onSubscribe(parent);
try {
// 调用 ObservableOnSubscribe 的 subscribe() 方法,开始发射数据
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
// 如果发生异常,调用 CreateEmitter 的 onError() 方法
parent.onError(ex);
}
}
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
// 保存传入的 Observer 对象
this.observer = observer;
}
@Override
public void onNext(T t) {
if (t == null) {
// 如果数据为 null,调用 onError() 方法
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {
// 如果没有取消订阅,调用观察者的 onNext() 方法
observer.onNext(t);
}
}
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
// 如果无法处理错误,打印错误信息
RxJavaPlugins.onError(t);
}
}
@Override
public boolean tryOnError(Throwable t) {
if (t == null) {
// 如果错误为 null,创建一个新的 NullPointerException
t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources."));
}
if (!isDisposed()) {
try {
// 如果没有取消订阅,调用观察者的 onError() 方法
observer.onError(t);
} finally {
// 取消订阅
dispose();
}
return true;
}
return false;
}
@Override
public void onComplete() {
if (!isDisposed()) {
try {
// 如果没有取消订阅,调用观察者的 onComplete() 方法
observer.onComplete();
} finally {
// 取消订阅
dispose();
}
}
}
@Override
public void setDisposable(Disposable d) {
// 设置 Disposable 对象
DisposableHelper.set(this, d);
}
@Override
public void setCancellable(Cancellable c) {
// 设置 Cancellable 对象
setDisposable(new CancellableDisposable(c));
}
@Override
public ObservableEmitter<T> serialize() {
// 返回一个序列化的 ObservableEmitter 对象
return new SerializedEmitter<T>(this);
}
@Override
public void dispose() {
// 取消订阅
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
// 判断是否已经取消订阅
return DisposableHelper.isDisposed(get());
}
}
}
在 ObservableCreate
类中,subscribeActual()
方法是核心方法,它会在 Observable
被订阅时调用。在该方法中,首先创建了一个 CreateEmitter
对象,然后调用观察者的 onSubscribe()
方法,接着调用 ObservableOnSubscribe
的 subscribe()
方法开始发射数据。
CreateEmitter
类实现了 ObservableEmitter
接口,用于发射数据、错误和完成信号。它会根据订阅状态和数据的有效性来决定是否调用观察者的相应方法。
just()
操作符用于创建一个 Observable
对象,它会依次发出传入的参数作为数据项。
import io.reactivex.Observable;
// 创建一个 Observable 对象,使用 just() 操作符
Observable<Integer> observable = Observable.just(1, 2, 3);
// 订阅 Observable 并打印接收到的数据
observable.subscribe(System.out::println);
在上述代码中,Observable.just(1, 2, 3)
创建了一个 Observable
对象,它会依次发出整数 1、2 和 3。
just()
方法有多个重载版本,这里以传入多个参数的版本为例进行分析:
public static <T> Observable<T> just(T item1, T item2, T item3) {
// 检查传入的参数是否为 null
ObjectHelper.requireNonNull(item1, "The first item is null");
ObjectHelper.requireNonNull(item2, "The second item is null");
ObjectHelper.requireNonNull(item3, "The third item is null");
// 创建一个 ObservableJust 对象,将参数作为数组传入
return RxJavaPlugins.onAssembly(new ObservableJust<T>(new Object[] { item1, item2, item3 }));
}
在上述代码中,just()
方法首先检查传入的参数是否为 null
,然后创建了一个 ObservableJust
对象,并将参数作为数组传入。最后,调用 RxJavaPlugins.onAssembly()
方法对 ObservableJust
对象进行一些全局的组装操作。
ObservableJust
类的源码如下:
public final class ObservableJust<T> extends Observable<T> implements ScalarCallable<T> {
private final T value;
public ObservableJust(final T value) {
// 保存传入的值
this.value = value;
}
@Override
protected void subscribeActual(Observer<? super T> s) {
// 创建一个 ScalarDisposable 对象,用于发射数据
ScalarDisposable<T> sd = new ScalarDisposable<T>(s, value);
// 调用观察者的 onSubscribe() 方法
s.onSubscribe(sd);
// 尝试发射数据
sd.run();
}
@Override
public T call() {
// 返回保存的值
return value;
}
static final class ScalarDisposable<T>
extends AtomicInteger
implements Disposable, Runnable {
private static final long serialVersionUID = 3880992722410194083L;
final Observer<? super T> observer;
final T value;
ScalarDisposable(Observer<? super T> observer, T value) {
// 保存观察者和值
this.observer = observer;
this.value = value;
}
@Override
public void run() {
if (get() == 0 && compareAndSet(0, 1)) {
try {
// 调用观察者的 onNext() 方法
observer.onNext(value);
if (get() == 1) {
// 调用观察者的 onComplete() 方法
lazySet(2);
observer.onComplete();
}
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
if (get() == 1) {
// 如果发生异常,调用观察者的 onError() 方法
lazySet(2);
observer.onError(ex);
} else {
// 打印错误信息
RxJavaPlugins.onError(ex);
}
}
}
}
@Override
public void dispose() {
// 取消订阅
set(2);
}
@Override
public boolean isDisposed() {
// 判断是否已经取消订阅
return get() == 2;
}
}
}
在 ObservableJust
类中,subscribeActual()
方法是核心方法,它会在 Observable
被订阅时调用。在该方法中,首先创建了一个 ScalarDisposable
对象,然后调用观察者的 onSubscribe()
方法,接着调用 ScalarDisposable
的 run()
方法开始发射数据。
ScalarDisposable
类实现了 Disposable
和 Runnable
接口,用于发射数据和处理取消订阅操作。在 run()
方法中,它会调用观察者的 onNext()
方法发射数据,然后调用 onComplete()
方法表示数据发射完成。
fromArray()
操作符用于创建一个 Observable
对象,它会依次发出数组中的元素作为数据项。
import io.reactivex.Observable;
// 创建一个数组
Integer[] array = {1, 2, 3};
// 创建一个 Observable 对象,使用 fromArray() 操作符
Observable<Integer> observable = Observable.fromArray(array);
// 订阅 Observable 并打印接收到的数据
observable.subscribe(System.out::println);
在上述代码中,Observable.fromArray(array)
创建了一个 Observable
对象,它会依次发出数组 array
中的元素。
fromArray()
方法的源码如下:
public static <T> Observable<T> fromArray(T... items) {
// 检查传入的数组是否为 null
ObjectHelper.requireNonNull(items, "items is null");
if (items.length == 0) {
// 如果数组长度为 0,返回一个空的 Observable 对象
return empty();
} else if (items.length == 1) {
// 如果数组长度为 1,返回一个只发出一个元素的 Observable 对象
return just(items[0]);
}
// 创建一个 ObservableFromArray 对象,将数组作为参数传入
return RxJavaPlugins.onAssembly(new ObservableFromArray<T>(items));
}
在上述代码中,fromArray()
方法首先检查传入的数组是否为 null
,然后根据数组的长度进行不同的处理。如果数组长度为 0,返回一个空的 Observable
对象;如果数组长度为 1,返回一个只发出一个元素的 Observable
对象;否则,创建一个 ObservableFromArray
对象,并将数组作为参数传入。最后,调用 RxJavaPlugins.onAssembly()
方法对 ObservableFromArray
对象进行一些全局的组装操作。
ObservableFromArray
类的源码如下:
public final class ObservableFromArray<T> extends Observable<T> {
final T[] array;
public ObservableFromArray(T[] array) {
// 保存传入的数组
this.array = array;
}
@Override
protected void subscribeActual(Observer<? super T> s) {
// 创建一个 FromArrayDisposable 对象,用于发射数据
FromArrayDisposable<T> d = new FromArrayDisposable<T>(s, array);
// 调用观察者的 onSubscribe() 方法
s.onSubscribe(d);
if (d.fusionMode) {
return;
}
// 发射数据
d.run();
}
static final class FromArrayDisposable<T>
extends BasicQueueDisposable<T> {
private static final long serialVersionUID = 3601286194409310724L;
final Observer<? super T> actual;
final T[] array;
int index;
boolean fusionMode;
FromArrayDisposable(Observer<? super T> actual, T[] array) {
// 保存观察者和数组
this.actual = actual;
this.array = array;
}
@Override
public int requestFusion(int mode) {
if ((mode & SYNC) != 0) {
// 如果支持同步融合模式,设置融合模式标志
fusionMode = true;
return SYNC;
}
return 0;
}
@Nullable
@Override
public T poll() throws Exception {
int i = index;
T[] a = array;
if (i != a.length) {
// 从数组中取出元素
index = i + 1;
return ObjectHelper.requireNonNull(a[i], "The array element is null");
}
return null;
}
@Override
public boolean isEmpty() {
// 判断数组是否已经遍历完
return index == array.length;
}
@Override
public void clear() {
// 清空数组索引
index = array.length;
}
@Override
public void dispose() {
// 取消订阅
index = array.length;
}
@Override
public boolean isDisposed() {
// 判断是否已经取消订阅
return index == array.length;
}
void run() {
T[] a = array;
int n = a.length;
for (int i = 0; i < n && !isDisposed(); i++) {
T value = a[i];
if (value == null) {
// 如果元素为 null,调用观察者的 onError() 方法
actual.onError(new NullPointerException("The element at index " + i + " is null"));
return;
}
// 调用观察者的 onNext() 方法
actual.onNext(value);
}
if (!isDisposed()) {
// 调用观察者的 onComplete() 方法
actual.onComplete();
}
}
}
}
在 ObservableFromArray
类中,subscribeActual()
方法是核心方法,它会在 Observable
被订阅时调用。在该方法中,首先创建了一个 FromArrayDisposable
对象,然后调用观察者的 onSubscribe()
方法,接着根据融合模式的设置决定是否发射数据。
FromArrayDisposable
类实现了 BasicQueueDisposable
接口,用于发射数据和处理取消订阅操作。在 run()
方法中,它会遍历数组,依次调用观察者的 onNext()
方法发射数据,最后调用 onComplete()
方法表示数据发射完成。
interval()
操作符用于创建一个 Observable
对象,它会按照指定的时间间隔依次发出从 0 开始的递增整数。
import io.reactivex.Observable;
import java.util.concurrent.TimeUnit;
// 创建一个 Observable 对象,使用 interval() 操作符,每隔 1 秒发出一个整数
Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS);
// 订阅 Observable 并打印接收到的数据
observable.subscribe(System.out::println);
// 为了让程序持续运行一段时间,休眠 5 秒
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
在上述代码中,Observable.interval(1, TimeUnit.SECONDS)
创建了一个 Observable
对象,它会每隔 1 秒发出一个从 0 开始的递增整数。
interval()
方法的源码如下:
public static Observable<Long> interval(long initialDelay, long period, TimeUnit unit, Scheduler scheduler) {
// 检查传入的参数是否为 null
ObjectHelper.requireNonNull(unit, "unit is null");
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
// 创建一个 ObservableInterval 对象,将参数传入
return RxJavaPlugins.onAssembly(new ObservableInterval(initialDelay, period, unit, scheduler));
}
在上述代码中,interval()
方法首先检查传入的参数是否为 null
,然后创建了一个 ObservableInterval
对象,并将参数传入。最后,调用 RxJavaPlugins.onAssembly()
方法对 ObservableInterval
对象进行一些全局的组装操作。
ObservableInterval
类的源码如下:
public final class ObservableInterval extends Observable<Long> {
final long initialDelay;
final long period;
final TimeUnit unit;
final Scheduler scheduler;
public ObservableInterval(long initialDelay, long period, TimeUnit unit, Scheduler scheduler) {
// 保存传入的参数
this.initialDelay = initialDelay;
this.period = period;
this.unit = unit;
this.scheduler = scheduler;
}
@Override
protected void subscribeActual(Observer<? super Long> observer) {
// 创建一个 IntervalObserver 对象,用于处理数据发射
IntervalObserver is = new IntervalObserver(observer);
// 调用观察者的 onSubscribe() 方法
observer.onSubscribe(is);
// 创建一个 Scheduler.Worker 对象,用于调度任务
Scheduler.Worker w = scheduler.createWorker();
// 设置 Disposable 对象
is.setResource(w);
// 调度任务,按照指定的时间间隔执行
w.schedulePeriodically(is, initialDelay, period, unit);
}
static final class IntervalObserver
extends AtomicReference<Disposable>
implements Disposable, Runnable {
private static final long serialVersionUID = 346773832286157679L;
final Observer<? super Long> actual;
long count;
IntervalObserver(Observer<? super Long> actual) {
// 保存观察者
this.actual = actual;
}
@Override
public void run() {
if (get() != DisposableHelper.DISPOSED) {
// 如果没有取消订阅,调用观察者的 onNext() 方法
actual.onNext(count++);
}
}
@Override
public void dispose() {
// 取消订阅
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
// 判断是否已经取消订阅
return get() == DisposableHelper.DISPOSED;
}
void setResource(Disposable d) {
// 设置 Disposable 对象
DisposableHelper.setOnce(this, d);
}
}
}
在 ObservableInterval
类中,subscribeActual()
方法是核心方法,它会在 Observable
被订阅时调用。在该方法中,首先创建了一个 IntervalObserver
对象,然后调用观察者的 onSubscribe()
方法,接着创建了一个 Scheduler.Worker
对象,用于调度任务。最后,调用 Scheduler.Worker
的 schedulePeriodically()
方法,按照指定的时间间隔执行 IntervalObserver
的 run()
方法。
IntervalObserver
类实现了 Disposable
和 Runnable
接口,用于处理数据发射和取消订阅操作。在 run()
方法中,它会调用观察者的 onNext()
方法发射数据,并递增计数器。
map()
操作符用于对 Observable
发出的每一个数据项进行转换,将其转换为另一种类型的数据项。
import io.reactivex.Observable;
// 创建一个 Observable 对象,发出整数 1、2、3
Observable<Integer> observable = Observable.just(1, 2, 3);
// 使用 map() 操作符将每个整数乘以 2
Observable<Integer> mappedObservable = observable.map(new Function<Integer, Integer>() {
@Override
public Integer apply(Integer value) throws Exception {
return value * 2;
}
});
// 订阅转换后的 Observable 并打印接收到的数据
mappedObservable.subscribe(System.out::println);
在上述代码中,map()
操作符将 Observable
发出的每个整数乘以 2,然后发出转换后的整数。
map()
方法的源码如下:
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
// 检查传入的 mapper 是否为 null
ObjectHelper.requireNonNull(mapper, "mapper is null");
// 创建一个 ObservableMap 对象,将当前 Observable 和 mapper 作为参数传入
return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
在上述代码中,map()
方法首先检查传入的 Function
对象是否为 null
,然后创建了一个 ObservableMap
对象,并将当前 Observable
和 mapper
作为参数传入。最后,调用 RxJavaPlugins.onAssembly()
方法对 ObservableMap
对象进行一些全局的组装操作。
ObservableMap
类的源码如下:
public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends U> function;
public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
// 调用父类的构造方法,保存上游 Observable
super(source);
// 保存传入的 mapper
this.function = function;
}
@Override
public void subscribeActual(Observer<? super U> t) {
// 创建一个 MapObserver 对象,将下游观察者和 mapper 作为参数传入
source.subscribe(new MapObserver<T, U>(t, function));
}
static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
final Function<? super T, ? extends U> mapper;
MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
// 调用父类的构造方法,保存下游观察者
super(actual);
// 保存传入的 mapper
this.mapper = mapper;
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
// 如果处于融合模式,直接传递数据
actual.onNext(null);
return;
}
U v;
try {
// 调用 mapper 的 apply() 方法进行数据转换
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
// 如果发生异常,调用父类的 onError() 方法
fail(ex);
return;
}
// 调用下游观察者的 onNext() 方法
actual.onNext(v);
}
@Override
public int requestFusion(int mode) {
// 尝试进行融合模式
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public U poll() throws Exception {
// 从上游获取数据并进行转换
T t = qs.poll();
return t != null ? ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.") : null;
}
}
}
在 ObservableMap
类中,subscribeActual()
方法是核心方法,它会在 Observable
被订阅时调用。在该方法中,创建了一个 MapObserver
对象,并将其作为下游观察者传递给上游 Observable
的 subscribe()
方法。
MapObserver
类实现了 BasicFuseableObserver
接口,用于处理数据转换和融合模式。在 onNext()
方法中,它会调用 mapper
的 apply()
方法对数据进行转换,然后将转换后的数据传递给下游观察者。
flatMap()
操作符用于将 Observable
发出的每个数据项转换为一个 Observable
,然后将这些 Observable
发出的数据合并成一个新的 Observable
。
import io.reactivex.Observable;
// 创建一个 Observable 对象,发出整数 1、2、3
Observable<Integer> observable = Observable.just(1, 2, 3);
// 使用 flatMap() 操作符将每个整数转换为一个 Observable,发出该整数的平方和立方
Observable<Integer> flatMappedObservable = observable.flatMap(new Function<Integer, ObservableSource<Integer>>() {
@Override
public ObservableSource<Integer> apply(Integer value) throws Exception {
return Observable.just(value * value, value * value * value);
}
});
// 订阅转换后的 Observable 并打印接收到的数据
flatMappedObservable.subscribe(System.out::println);
在上述代码中,flatMap()
操作符将 Observable
发出的每个整数转换为一个 Observable
,该 Observable
发出该整数的平方和立方,然后将这些 Observable
发出的数据合并成一个新的 Observable
。
flatMap()
方法的源码如下:
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper) {
// 检查传入的 mapper 是否为 null
ObjectHelper.requireNonNull(mapper, "mapper is null");
// 创建一个 ObservableFlatMap 对象,将当前 Observable 和 mapper 作为参数传入
return flatMap(mapper, false);
}
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper, boolean delayErrors) {
// 检查传入的 mapper 是否为 null
ObjectHelper.requireNonNull(mapper, "mapper is null");
// 创建一个 ObservableFlatMap 对象,将当前 Observable、mapper 和 delayErrors 作为参数传入
return RxJavaPlugins.onAssembly(new ObservableFlatMap<T, R>(this, mapper, delayErrors, Integer.MAX_VALUE));
}
flatMap()
方法的源码如下:
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper) {
// 检查传入的 mapper 是否为 null
ObjectHelper.requireNonNull(mapper, "mapper is null");
// 创建一个 ObservableFlatMap对象,将当前 Observable 和 mapper 作为参数传入
return flatMap(mapper, false);
}
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper, boolean delayErrors) {
// 检查传入的 mapper 是否为 null
ObjectHelper.requireNonNull(mapper, "mapper is null");
// 创建一个 ObservableFlatMap 对象,将当前 Observable、mapper 和 delayErrors 作为参数传入
return RxJavaPlugins.onAssembly(new ObservableFlatMap<T, R>(this, mapper, delayErrors, Integer.MAX_VALUE));
}
在上述代码中,flatMap()
方法首先对传入的 mapper
函数进行非空校验,确保转换逻辑的有效性。然后通过调用重载的 flatMap()
方法,创建 ObservableFlatMap
实例,并将上游 Observable
、转换函数 mapper
、是否延迟错误处理的标志 delayErrors
以及最大并发数(这里设置为 Integer.MAX_VALUE
)传入。
ObservableFlatMap
类的核心代码如下:
public final class ObservableFlatMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends ObservableSource<? extends U>> mapper;
final boolean delayErrors;
final int maxConcurrency;
public ObservableFlatMap(ObservableSource<T> source, Function<? super T, ? extends ObservableSource<? extends U>> mapper,
boolean delayErrors, int maxConcurrency) {
super(source);
this.mapper = mapper;
this.delayErrors = delayErrors;
this.maxConcurrency = maxConcurrency;
}
@Override
public void subscribeActual(Observer<? super U> observer) {
// 创建一个 MergeObserver 实例,用于处理合并逻辑
if (getClass() == ObservableFlatMap.class) {
source.subscribe(new MergeObserver<T, U>(observer, mapper, delayErrors, maxConcurrency));
} else {
// 其他情况的处理,这里暂不展开
source.subscribe(new BlockingOperatorMergeSubscriber<T, U>(observer, mapper, delayErrors, maxConcurrency));
}
}
static final class MergeObserver<T, U> extends BasicFuseableObserver<T, U>
implements Observer<T>, Disposable, InnerObserver<U>, Runnable, QueueDisposable<U> {
private static final long serialVersionUID = -7720116335840841829L;
final Observer<? super U> actual;
final Function<? super T, ? extends ObservableSource<? extends U>> mapper;
final boolean delayErrors;
final int maxConcurrency;
// 用于存储上游发送的数据转换后的 Observable 对应的 Disposable
final List<Disposable> sources = new ArrayList<>();
// 用于存储上游发送的数据转换后的 Observable 发出的数据
final Queue<U> queue = new SpscLinkedArrayQueue<>(QueueDisposable.bufferSize());
// 用于控制并发数量
int wip;
// 记录错误信息
Throwable error;
// 标记是否完成
boolean done;
// 用于取消订阅
Disposable s;
MergeObserver(Observer<? super U> actual, Function<? super T, ? extends ObservableSource<? extends U>> mapper,
boolean delayErrors, int maxConcurrency) {
this.actual = actual;
this.mapper = mapper;
this.delayErrors = delayErrors;
this.maxConcurrency = maxConcurrency;
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.validate(this.s, s)) {
this.s = s;
actual.onSubscribe(this);
}
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
// 如果处于融合模式,直接处理数据
queue.offer(null);
return;
}
try {
// 使用 mapper 函数将上游数据转换为新的 Observable
ObservableSource<? extends U> source = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper returned a null ObservableSource");
// 订阅转换后的 Observable
source.subscribe(this);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.dispose();
onError(ex);
}
}
@Override
public void onError(Throwable t) {
if (done) {
RxJavaPlugins.onError(t);
return;
}
error = t;
if (delayErrors) {
// 如果是延迟错误处理,只有在所有上游 Observable 都完成后才通知下游
drain();
} else {
s.dispose();
actual.onError(t);
}
}
@Override
public void onComplete() {
done = true;
drain();
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.add(sources, s)) {
// 如果添加成功,判断是否需要增加并发处理
if (sources.size() == 1 && wip == 0) {
s.dispose();
actual.onError(new CompositeException(sources));
return;
}
if (maxConcurrency != Integer.MAX_VALUE && sources.size() == maxConcurrency) {
// 如果达到最大并发数,取消多余的订阅
for (Disposable d : sources) {
if (d != s) {
d.dispose();
}
}
sources.clear();
}
} else {
s.dispose();
}
}
@Override
public void onNext(U t) {
// 将转换后的 Observable 发出的数据放入队列
queue.offer(t);
drain();
}
@Override
public void onError(Throwable t) {
if (delayErrors) {
// 如果是延迟错误处理,将错误信息暂存
error = ExceptionHelper.addThrowable(error, t);
} else {
for (Disposable d : sources) {
d.dispose();
}
sources.clear();
actual.onError(t);
}
}
@Override
public void onComplete() {
if (sources.remove(this)) {
// 移除当前完成的 Observable 对应的 Disposable
drain();
}
}
void drain() {
if (wip != 0 ||!QueueDisposableHelper.openSubscription(this, queue)) {
return;
}
int missed = 1;
final Observer<? super U> a = actual;
final List<Disposable> sources = this.sources;
final Queue<U> q = queue;
for (;;) {
for (; ; ) {
boolean d = done;
U v;
try {
v = q.poll();
} catch (Throwable ex) {
for (Disposable s : sources) {
s.dispose();
}
sources.clear();
q.clear();
a.onError(ex);
return;
}
boolean empty = v == null;
if (checkTerminated(d, empty, a)) {
return;
}
if (empty) {
break;
}
a.onNext(v);
}
missed = wip - missed;
if (missed == 0) {
break;
}
wip = 0;
}
}
boolean checkTerminated(boolean d, boolean empty, Observer<? super U> a) {
if (d) {
if (delayErrors) {
if (error != null) {
a.onError(error);
} else {
a.onComplete();
}
} else if (empty) {
Throwable e = error;
if (e != null) {
a.onError(e);
} else {
a.onComplete();
}
}
return true;
}
return false;
}
@Override
public void dispose() {
// 取消所有相关的订阅
s.dispose();
for (Disposable d : sources) {
d.dispose();
}
sources.clear();
queue.clear();
}
@Override
public boolean isDisposed() {
return s.isDisposed();
}
@Override
public void run() {
drain();
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public U poll() throws Exception {
return queue.poll();
}
@Override
public boolean isEmpty() {
return queue.isEmpty();
}
@Override
public void clear() {
queue.clear();
}
}
}
在 ObservableFlatMap
类中,subscribeActual
方法会根据不同情况创建 MergeObserver
或其他类型的观察者。MergeObserver
类是实现 flatMap
逻辑的核心。
在 onNext
方法中,它将上游 Observable
发出的数据通过 mapper
函数转换为新的 Observable
,并订阅该 Observable
。当转换后的 Observable
发出数据时,onNext
方法会将数据放入 queue
队列中,并调用 drain
方法处理数据。
drain
方法是数据处理和合并的关键。它从队列中取出数据,并将其发送给下游 Observer
。同时,它还负责处理错误和完成信号,根据 delayErrors
的设置决定何时通知下游 Observer
错误信息。如果所有上游 Observable
都已完成且没有错误,drain
方法会通知下游 Observer
数据发送完成。
MergeObserver
还实现了 QueueDisposable
接口,用于支持融合模式(fusion mode),在某些情况下可以提高数据处理的效率,减少数据在队列中的传递开销 。整个 flatMap
操作符通过这些复杂的逻辑,实现了将上游 Observable
发出的数据转换为多个 Observable
,并将它们发出的数据合并成一个新的 Observable
的功能。
concatMap()
操作符与 flatMap()
类似,也是将 Observable
发出的每个数据项转换为一个 Observable
,但不同的是,concatMap()
会按照数据项发出的顺序,依次将转换后的 Observable
进行合并,前一个 Observable
发送完成后,才会开始订阅并接收下一个 Observable
发出的数据。
import io.reactivex.Observable;
// 创建一个 Observable 对象,发出整数 1、2、3
Observable<Integer> observable = Observable.just(1, 2, 3);
// 使用 concatMap() 操作符将每个整数转换为一个 Observable,发出该整数的平方和立方
Observable<Integer> concatMappedObservable = observable.concatMap(new io.reactivex.functions.Function<Integer, io.reactivex.ObservableSource<Integer>>() {
@Override
public io.reactivex.ObservableSource<Integer> apply(Integer value) throws Exception {
return Observable.just(value * value, value * value * value);
}
});
// 订阅转换后的 Observable 并打印接收到的数据
concatMappedObservable.subscribe(System.out::println);
在上述代码中,concatMap()
操作符先将整数 1 转换为 Observable
并发出其平方和立方,等这个 Observable
发送完成后,再对整数 2 进行同样操作,以此类推。
concatMap()
方法在 Observable
类中定义如下:
public final <R> Observable<R> concatMap(Function<? super T,? extends ObservableSource<? extends R>> mapper) {
// 检查传入的 mapper 是否为 null
ObjectHelper.requireNonNull(mapper, "mapper is null");
// 创建一个 ObservableConcatMap 对象,将当前 Observable 和 mapper 作为参数传入
return RxJavaPlugins.onAssembly(new ObservableConcatMap<T, R>(this, mapper));
}
这里首先对 mapper
进行非空校验,然后创建 ObservableConcatMap
实例,将上游 Observable
和转换函数 mapper
传入,同时通过 RxJavaPlugins.onAssembly()
方法进行一些全局的组装操作。
ObservableConcatMap
类继承自 AbstractObservableWithUpstream
,其核心代码如下:
public final class ObservableConcatMap<T, R> extends AbstractObservableWithUpstream<T, R> {
final Function<? super T,? extends ObservableSource<? extends R>> mapper;
public ObservableConcatMap(ObservableSource<T> source, Function<? super T,? extends ObservableSource<? extends R>> mapper) {
super(source);
this.mapper = mapper;
}
@Override
public void subscribeActual(Observer<? super R> s) {
// 创建一个 ConcatMapObserver 实例,用于处理合并逻辑
source.subscribe(new ConcatMapObserver<T, R>(s, mapper));
}
static final class ConcatMapObserver<T, R> extends BasicFuseableObserver<T, R>
implements Observer<T>, Disposable, InnerObserver<R>, Runnable {
private static final long serialVersionUID = -4480924777014457855L;
final Observer<? super R> actual;
final Function<? super T,? extends ObservableSource<? extends R>> mapper;
// 用于存储上游发送的数据转换后的 Observable 对应的 Disposable
final ArrayList<Disposable> sources = new ArrayList<>();
// 记录当前正在处理的 Observable 的索引
int index;
// 用于控制并发处理,类似于一个信号量
int wip;
// 记录错误信息
Throwable error;
// 标记是否完成
boolean done;
// 用于取消订阅
Disposable s;
ConcatMapObserver(Observer<? super R> actual, Function<? super T,? extends ObservableSource<? extends R>> mapper) {
this.actual = actual;
this.mapper = mapper;
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.validate(this.s, s)) {
this.s = s;
actual.onSubscribe(this);
}
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
// 如果处于融合模式,直接处理数据
actual.onNext(null);
return;
}
try {
// 使用 mapper 函数将上游数据转换为新的 Observable
ObservableSource<? extends R> source = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper returned a null ObservableSource");
// 创建一个 InnerConcatObserver 来订阅转换后的 Observable
source.subscribe(new InnerConcatObserver<>(this));
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.dispose();
onError(ex);
}
}
@Override
public void onError(Throwable t) {
if (done) {
RxJavaPlugins.onError(t);
return;
}
error = t;
done = true;
drain();
}
@Override
public void onComplete() {
done = true;
drain();
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.add(sources, s)) {
// 如果添加成功,判断是否需要开始处理
if (sources.size() == 1 && wip == 0) {
s.dispose();
actual.onError(new CompositeException(sources));
return;
}
} else {
s.dispose();
}
}
@Override
public void onNext(R t) {
actual.onNext(t);
}
@Override
public void onError(Throwable t) {
error = ExceptionHelper.addThrowable(error, t);
done = true;
drain();
}
@Override
public void onComplete() {
if (DisposableHelper.remove(sources, this)) {
drain();
}
}
void drain() {
if (wip != 0 || sources.isEmpty()) {
return;
}
int missed = 1;
final Observer<? super R> a = actual;
final ArrayList<Disposable> sources = this.sources;
for (;;) {
if (checkTerminated(done, a)) {
return;
}
while (index < sources.size()) {
Disposable d = sources.get(index);
if (!d.isDisposed()) {
// 开始订阅当前的 Observable
((InnerConcatObserver<R>)d).subscribeInner();
index++;
return;
}
index++;
}
index = 0;
missed = wip - missed;
if (missed == 0) {
break;
}
wip = 0;
}
}
boolean checkTerminated(boolean d, Observer<? super R> a) {
if (d) {
Throwable e = error;
if (e != null) {
a.onError(e);
} else {
a.onComplete();
}
return true;
}
return false;
}
@Override
public void dispose() {
s.dispose();
for (Disposable d : sources) {
d.dispose();
}
sources.clear();
}
@Override
public boolean isDisposed() {
return s.isDisposed();
}
@Override
public void run() {
drain();
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public R poll() throws Exception {
return null;
}
static final class InnerConcatObserver<R> extends AtomicReference<Disposable>
implements Disposable, InnerObserver<R> {
private static final long serialVersionUID = -3074621840686372182L;
final ConcatMapObserver<?, R> parent;
InnerConcatObserver(ConcatMapObserver<?, R> parent) {
this.parent = parent;
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.setOnce(this, s)) {
parent.sources.add(this);
if (parent.sources.size() == 1 && parent.wip == 0) {
s.dispose();
parent.actual.onError(new CompositeException(parent.sources));
}
} else {
s.dispose();
}
}
@Override
public void onNext(R t) {
parent.actual.onNext(t);
}
@Override
public void onError(Throwable t) {
parent.error = ExceptionHelper.addThrowable(parent.error, t);
parent.done = true;
parent.drain();
}
@Override
public void onComplete() {
if (DisposableHelper.remove(parent.sources, this)) {
parent.drain();
}
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
void subscribeInner() {
get().dispose();
get().subscribe(this);
}
}
}
}
在 ObservableConcatMap
类中,subscribeActual
方法创建 ConcatMapObserver
实例来处理订阅逻辑。ConcatMapObserver
类实现了多个接口,其中 onNext
方法会将上游数据通过 mapper
转换为新的 Observable
,并创建 InnerConcatObserver
来订阅该 Observable
。
drain
方法是实现按顺序合并的关键。它会从 sources
列表中依次取出 Disposable
,并订阅对应的 Observable
。只有当前 Observable
发送完成(onComplete
被调用),才会继续处理下一个 Observable
。如果在处理过程中出现错误(onError
被调用),则会立即停止并将错误传递给下游 Observer
。
通过这种机制,concatMap()
操作符确保了转换后的 Observable
按照上游数据发出的顺序依次进行合并,从而实现了有序的数据处理和传递 ,相比 flatMap()
更适合对数据顺序有严格要求的场景。
buffer()
操作符用于将 Observable
发出的数据收集到指定大小的缓冲区中,当缓冲区满了或者达到一定的时间间隔后,将缓冲区作为一个数据项发出。
import io.reactivex.Observable;
import java.util.List;
// 创建一个 Observable 对象,每隔 1 秒发出一个整数
Observable<Long> observable = Observable.interval(1, java.util.concurrent.TimeUnit.SECONDS);
// 使用 buffer() 操作符,将每 3 个数据收集到一个缓冲区
observable.buffer(3)
.subscribe(new io.reactivex.Observer<List<Long>>() {
@Override
public void onSubscribe(io.reactivex.disposables.Disposable d) {
System.out.println("开始订阅");
}
@Override
public void onNext(List<Long> buffer) {
System.out.println("接收到缓冲区数据: " + buffer);
}
@Override
public void onError(Throwable e) {
System.out.println("发生错误: " + e.getMessage());
}
@Override
public void onComplete() {
System.out.println("数据发送完成");
}
});
// 为了让程序持续运行一段时间,休眠 10 秒
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
在上述代码中,buffer(3)
使得 Observable
每发出 3 个数据,就将这 3 个数据组成一个 List
发送出来。
buffer()
方法在 Observable
类中有多个重载版本,这里分析最常用的按数量收集的版本:
public final Observable<List<T>> buffer(int count) {
// 检查 count 是否合法(大于 0)
ObjectHelper.verifyPositive(count, "count");
// 创建一个 ObservableBufferCount 对象,将当前 Observable 和 count 作为参数传入
return RxJavaPlugins.onAssembly(new ObservableBufferCount<T>(this, count));
}
这里先对 count
进行合法性校验,确保其大于 0,然后创建 ObservableBufferCount
实例,将上游 Observable
和缓冲区大小 count
传入,并通过 RxJavaPlugins.onAssembly()
进行全局组装。
ObservableBufferCount
类继承自 AbstractObservableWithUpstream
,其核心代码如下:
public final class ObservableBufferCount<T> extends AbstractObservableWithUpstream<T, List<T>> {
final int count;
public ObservableBufferCount(ObservableSource<T> source, int count) {
super(source);
this.count = count;
}
@Override
public void subscribeActual(Observer<? super List<T>> s) {
// 创建一个 BufferObserver 实例,用于处理缓冲区逻辑
source.subscribe(new BufferObserver<T>(s, count));
}
static final class BufferObserver<T> extends BasicFuseableObserver<T, List<T>>
implements Disposable {
private static final long serialVersionUID = -2834885649622276437L;
final Observer<? super List<T>> actual;
final int count;
// 用于存储缓冲区数据
final ArrayList<T> list;
// 用于取消订阅
Disposable s;
BufferObserver(Observer<? super List<T>> actual, int count) {
this.actual = actual;
this.count = count;
this.list = new ArrayList<>();
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.validate(this.s, s)) {
this.s = s;
actual.onSubscribe(this);
}
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
// 如果处于融合模式,直接处理数据
actual.onNext(null);
return;
}
list.add(t);
if (list.size() == count) {
// 如果缓冲区满了,将缓冲区数据发送给下游,并清空缓冲区
ArrayList<T> local = list;
list.clear();
actual.onNext(local);
}
}
@Override
public void onError(Throwable t) {
if (done) {
RxJavaPlugins.onError(t);
return;
}
done = true;
list.clear();
actual.onError(t);
}
@Override
public void onComplete() {
if (done) {
return;
}
done = true;
if (!list.isEmpty()) {
// 如果缓冲区还有剩余数据,将其发送给下游
actual.onNext(list);
}
actual.onComplete();
}
@Override
public void dispose() {
s.dispose();
list.clear();
}
@Override
public boolean isDisposed() {
return s.isDisposed();
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public List<T> poll() throws Exception {
if (sourceMode == SYNC) {
if (list.isEmpty()) {
return null;
}
ArrayList<T> local = list;
list.clear();
return local;
}
return null;
}
}
}
在 ObservableBufferCount
类中,subscribeActual
方法创建 BufferObserver
实例来处理订阅逻辑。BufferObserver
类的 onNext
方法会将上游数据添加到 list
缓冲区中,当缓冲区大小达到 count
时,将缓冲区数据组成 List
发送给下游 Observer
,并清空缓冲区。
在 onComplete
方法中,如果在 Observable
完成时缓冲区还有剩余数据,也会将这些数据组成 List
发送给下游 Observer
,确保所有数据都能被处理。通过这种方式,buffer()
操作符实现了将连续的数据收集到缓冲区并按批次发出的功能,方便对数据进行批量处理 。
filter()
操作符用于从Observable
发出的数据中筛选出符合特定条件的数据项,只有满足条件的数据才会被发送给下游的Observer
。
import io.reactivex.Observable;
// 创建一个Observable对象,发出整数1到10
Observable<Integer> observable = Observable.range(1, 10);
// 使用filter()操作符筛选出偶数
Observable<Integer> filteredObservable = observable.filter(new io.reactivex.functions.Predicate<Integer>() {
@Override
public boolean test(Integer value) throws Exception {
return value % 2 == 0;
}
});
// 订阅过滤后的Observable并打印接收到的数据
filteredObservable.subscribe(System.out::println);
在上述代码中,filter()
操作符通过Predicate
函数定义筛选条件,只允许偶数通过并发送给下游Observer
。
filter()
方法在Observable
类中定义如下:
public final Observable<T> filter(Predicate<? super T> predicate) {
// 检查传入的Predicate是否为null
ObjectHelper.requireNonNull(predicate, "predicate is null");
// 创建一个ObservableFilter对象,将当前Observable和Predicate作为参数传入
return RxJavaPlugins.onAssembly(new ObservableFilter<T>(this, predicate));
}
该方法首先对Predicate
进行非空校验,然后创建ObservableFilter
实例,并通过RxJavaPlugins.onAssembly()
方法进行全局组装操作。
ObservableFilter
类继承自AbstractObservableWithUpstream
,其核心代码如下:
public final class ObservableFilter<T> extends AbstractObservableWithUpstream<T, T> {
final Predicate<? super T> predicate;
public ObservableFilter(ObservableSource<T> source, Predicate<? super T> predicate) {
super(source);
this.predicate = predicate;
}
@Override
public void subscribeActual(Observer<? super T> s) {
// 创建一个FilterObserver实例,用于处理过滤逻辑
source.subscribe(new FilterObserver<T>(s, predicate));
}
static final class FilterObserver<T> extends BasicFuseableObserver<T, T> {
private static final long serialVersionUID = -3009044653058046526L;
final Predicate<? super T> predicate;
FilterObserver(Observer<? super T> actual, Predicate<? super T> predicate) {
super(actual);
this.predicate = predicate;
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
// 如果处于融合模式,直接处理数据
actual.onNext(null);
return;
}
try {
if (predicate.test(t)) {
// 如果数据满足条件,将其发送给下游Observer
actual.onNext(t);
}
} catch (Throwable e) {
// 如果在判断条件时发生异常,通知下游Observer错误
fail(e);
}
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public T poll() throws Exception {
T v;
for (;;) {
v = qs.poll();
if (v == null) {
return null;
}
if (predicate.test(v)) {
// 在融合模式下,从队列中取出满足条件的数据
return v;
}
}
}
}
}
在ObservableFilter
类中,subscribeActual
方法创建FilterObserver
实例来处理订阅逻辑。FilterObserver
类的onNext
方法在接收到上游Observable
的数据后,调用Predicate
的test
方法判断数据是否满足条件。如果满足条件,则将数据发送给下游Observer
;如果不满足条件,则直接忽略该数据。在融合模式下,poll
方法会从队列中不断取出数据进行条件判断,直到找到满足条件的数据返回给下游,从而实现高效的数据过滤。
distinct()
操作符用于过滤掉Observable
发出的重复数据项,只允许第一次出现的数据通过并发送给下游Observer
。
import io.reactivex.Observable;
// 创建一个Observable对象,发出数据1, 2, 2, 3, 1, 4
Observable<Integer> observable = Observable.just(1, 2, 2, 3, 1, 4);
// 使用distinct()操作符过滤重复数据
Observable<Integer> distinctObservable = observable.distinct();
// 订阅过滤后的Observable并打印接收到的数据
distinctObservable.subscribe(System.out::println);
在上述代码中,distinct()
操作符会将重复的数据2
和1
过滤掉,最终下游Observer
只会收到1, 2, 3, 4
。
distinct()
方法在Observable
类中定义如下:
public final Observable<T> distinct() {
// 创建一个ObservableDistinct对象,将当前Observable作为参数传入
return RxJavaPlugins.onAssembly(new ObservableDistinct<T>(this));
}
该方法直接创建ObservableDistinct
实例,并通过RxJavaPlugins.onAssembly()
方法进行全局组装。
ObservableDistinct
类继承自AbstractObservableWithUpstream
,其核心代码如下:
public final class ObservableDistinct<T> extends AbstractObservableWithUpstream<T, T> {
public ObservableDistinct(ObservableSource<T> source) {
super(source);
}
@Override
public void subscribeActual(Observer<? super T> s) {
// 创建一个DistinctObserver实例,用于处理去重逻辑
source.subscribe(new DistinctObserver<T>(s));
}
static final class DistinctObserver<T> extends BasicFuseableObserver<T, T> {
private static final long serialVersionUID = -5580183291188949823L;
// 使用HashSet存储已经出现过的数据
final Set<T> set;
DistinctObserver(Observer<? super T> actual) {
super(actual);
// 初始化HashSet
this.set = new HashSet<T>();
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
// 如果处于融合模式,直接处理数据
actual.onNext(null);
return;
}
if (set.add(t)) {
// 如果数据在Set中不存在(即第一次出现),将其发送给下游Observer
actual.onNext(t);
}
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public T poll() throws Exception {
T v;
for (;;) {
v = qs.poll();
if (v == null) {
return null;
}
if (set.add(v)) {
// 在融合模式下,从队列中取出不重复的数据
return v;
}
}
}
}
}
在ObservableDistinct
类中,subscribeActual
方法创建DistinctObserver
实例来处理订阅逻辑。DistinctObserver
类中通过一个HashSet
来存储已经出现过的数据。在onNext
方法中,每接收到上游Observable
的数据,就尝试将其添加到HashSet
中。由于HashSet
不允许重复元素,当add
方法返回true
时,说明该数据是第一次出现,此时将数据发送给下游Observer
;如果add
方法返回false
,则说明数据已经出现过,直接忽略该数据。在融合模式下,poll
方法同样利用HashSet
的特性,从队列中筛选出不重复的数据返回给下游,实现数据去重的功能。
take()
操作符用于从Observable
发出的数据中只取前n
个数据项发送给下游Observer
,在获取到指定数量的数据后,Observable
会自动发出完成信号。
import io.reactivex.Observable;
// 创建一个Observable对象,发出整数1到10
Observable<Integer> observable = Observable.range(1, 10);
//使用take()操作符只取前5个数据
Observable<Integer> takeObservable = observable.take(5);
//订阅处理后的Observable并打印接收到的数据
takeObservable.subscribe(System.out::println);
在上述代码中,take(5)
使得下游Observer
只会接收到前5个数据,即1, 2, 3, 4, 5
,之后Observable
会发出完成信号。
take()
方法在Observable
类中定义如下:
public final Observable<T> take(long count) {
// 检查count是否合法(大于等于0)
if (count < 0) {
throw new IllegalArgumentException("count < 0: " + count);
}
// 如果count为0,直接返回一个空的Observable
if (count == 0L) {
return RxJavaPlugins.onAssembly(Observable.empty());
}
// 创建一个ObservableTake对象,将当前Observable和count作为参数传入
return RxJavaPlugins.onAssembly(new ObservableTake<T>(this, count));
}
该方法首先对count
进行合法性校验,确保其大于等于0。如果count
为0,则返回一个空的Observable
;否则创建ObservableTake
实例,并通过RxJavaPlugins.onAssembly()
方法进行全局组装。
ObservableTake
类继承自AbstractObservableWithUpstream
,其核心代码如下:
public final class ObservableTake<T> extends AbstractObservableWithUpstream<T, T> {
final long count;
public ObservableTake(ObservableSource<T> source, long count) {
super(source);
this.count = count;
}
@Override
public void subscribeActual(Observer<? super T> s) {
// 根据count的不同情况创建不同的Observer
if (count == Long.MAX_VALUE) {
source.subscribe(s);
} else {
source.subscribe(new TakeObserver<T>(s, count));
}
}
static final class TakeObserver<T> extends BasicFuseableObserver<T, T> {
private static final long serialVersionUID = -9064447276924681822L;
long remaining;
TakeObserver(Observer<? super T> actual, long count) {
super(actual);
this.remaining = count;
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
// 如果处于融合模式,直接处理数据
actual.onNext(null);
return;
}
long r = remaining;
if (r == 1) {
// 如果只剩下一个数据,将其发送给下游Observer并发出完成信号
done = true;
actual.onNext(t);
actual.onComplete();
} else {
// 将数据发送给下游Observer,并减少剩余数据数量
actual.onNext(t);
remaining = r - 1;
}
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public T poll() throws Exception {
if (sourceMode == SYNC) {
long r = remaining;
if (r == 1) {
// 在融合模式下,当只剩下一个数据时,取出数据并发出完成信号
done = true;
T v = qs.poll();
actual.onComplete();
return v;
} else if (r > 0) {
// 在融合模式下,取出数据并减少剩余数量
remaining = r - 1;
return qs.poll();
}
return null;
}
return null;
}
}
}
在ObservableTake
类中,subscribeActual
方法根据count
的值决定如何订阅上游Observable
。如果count
为Long.MAX_VALUE
,则直接将下游Observer
订阅到上游Observable
;否则创建TakeObserver
实例。TakeObserver
类的onNext
方法在接收到上游数据后,会检查剩余需要获取的数据数量remaining
。当remaining
为1时,将数据发送给下游Observer
并发出完成信号;否则将数据发送给下游Observer
并减少remaining
的值。在融合模式下,poll
方法同样根据remaining
的值来决定是否继续从队列中取出数据以及何时发出完成信号,从而实现按数量截取数据的功能。
merge()
操作符用于将多个Observable
合并为一个Observable
,合并后的Observable
会按照数据项发出的顺序,将所有Observable
发出的数据依次发送给下游Observer
。当所有的Observable
都完成时,合并后的Observable
才会发出完成信号。
import io.reactivex.Observable;
// 创建两个Observable对象
Observable<Integer> observable1 = Observable.just(1, 2, 3);
Observable<Integer> observable2 = Observable.just(4, 5, 6);
// 使用merge()操作符合并两个Observable
Observable<Integer> mergedObservable = Observable.merge(observable1, observable2);
// 订阅合并后的Observable并打印接收到的数据
mergedObservable.subscribe(System.out::println);
在上述代码中,merge()
操作符将observable1
和observable2
合并,下游Observer
会依次收到1, 2, 3, 4, 5, 6
。
merge()
方法有多个重载版本,以下是接收多个Observable
参数的版本源码:
@SafeVarargs
public static <T> Observable<T> merge(ObservableSource<? extends T>... sources) {
// 检查传入的Observable数组是否为null
ObjectHelper.requireNonNull(sources, "sources is null");
// 如果只有一个Observable,直接返回该Observable
if (sources.length == 1) {
@SuppressWarnings("unchecked")
ObservableSource<T> s = (ObservableSource<T>)sources[0];
return RxJavaPlugins.onAssembly((Observable<T>)s);
}
// 创建一个ObservableMerge对象,将多个Observable作为参数传入
return RxJavaPlugins.onAssembly(new ObservableMerge<>(sources));
}
该方法首先对传入的Observable
数组进行非空校验。如果数组只有一个元素,直接返回该元素对应的Observable
;否则创建ObservableMerge
实例,并通过RxJavaPlugins.onAssembly()
方法进行全局组装。
ObservableMerge
类继承自AbstractObservableWithUpstream
,其核心代码如下:
public final class ObservableMerge<T> extends AbstractObservableWithUpstream<ObservableSource<? extends T>, T> {
final ObservableSource<? extends T>[] sources;
@SafeVarargs
public ObservableMerge(ObservableSource<? extends T>... sources) {
super(Observable.fromArray(sources));
this.sources = sources;
}
@Override
public void subscribeActual(Observer<? super T> s) {
// 创建一个MergeObserver实例,用于处理合并逻辑
MergeObserver<T> mergeObserver = new MergeObserver<>(s);
s.onSubscribe(mergeObserver);
for (ObservableSource<? extends T> source : sources) {
if (source == null) {
// 如果有Observable为null,发出错误信号
mergeObserver.onError(new NullPointerException("One of the sources is null"));
return;
}
// 订阅每个Observable,并将MergeObserver作为观察者
source.subscribe(mergeObserver);
}
}
static final class MergeObserver<T> extends BasicFuseableObserver<ObservableSource<? extends T>, T>
implements Observer<ObservableSource<? extends T>>, Disposable, InnerObserver<T>, Runnable, QueueDisposable<T> {
private static final long serialVersionUID = -7720116335840841829L;
final Observer<? super T> actual;
// 用于存储所有Observable对应的Disposable
final ArrayList<Disposable> sources = new ArrayList<>();
// 用于存储Observable发出的数据
final Queue<T> queue = new SpscLinkedArrayQueue<>(QueueDisposable.bufferSize());
// 用于控制并发处理
int wip;
// 记录错误信息
Throwable error;
// 标记是否所有Observable都已完成
boolean done;
// 用于取消订阅
Disposable s;
MergeObserver(Observer<? super T> actual) {
this.actual = actual;
}
@Override
public void onSubscribe(Disposable s) {
if
接上分析 MergeObserver
类的剩余部分以及整个 merge()
操作符的工作原理。
MergeObserver
类的完整分析static final class MergeObserver<T> extends BasicFuseableObserver<ObservableSource<? extends T>, T>
implements Observer<ObservableSource<? extends T>>, Disposable, InnerObserver<T>, Runnable, QueueDisposable<T> {
private static final long serialVersionUID = -7720116335840841829L;
final Observer<? super T> actual;
// 用于存储所有Observable对应的Disposable
final ArrayList<Disposable> sources = new ArrayList<>();
// 用于存储Observable发出的数据
final Queue<T> queue = new SpscLinkedArrayQueue<>(QueueDisposable.bufferSize());
// 用于控制并发处理
int wip;
// 记录错误信息
Throwable error;
// 标记是否所有Observable都已完成
boolean done;
// 用于取消订阅
Disposable s;
MergeObserver(Observer<? super T> actual) {
this.actual = actual;
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.validate(this.s, s)) {
this.s = s;
actual.onSubscribe(this);
}
}
@Override
public void onNext(ObservableSource<? extends T> t) {
if (done) {
return;
}
if (sourceMode != NONE) {
// 如果处于融合模式,直接处理数据
actual.onNext(null);
return;
}
try {
// 创建一个InnerObserver来订阅每个Observable
InnerObserver<T> inner = new InnerObserver<>(this);
// 存储该Observable对应的Disposable
sources.add(inner);
// 订阅当前的Observable
t.subscribe(inner);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.dispose();
onError(ex);
}
}
@Override
public void onError(Throwable t) {
if (done) {
RxJavaPlugins.onError(t);
return;
}
error = t;
done = true;
drain();
}
@Override
public void onComplete() {
done = true;
drain();
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.add(sources, s)) {
if (sources.size() == 1 && wip == 0) {
s.dispose();
actual.onError(new CompositeException(sources));
return;
}
} else {
s.dispose();
}
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
actual.onNext(null);
return;
}
// 将接收到的数据存入队列
queue.offer(t);
drain();
}
@Override
public void onError(Throwable t) {
if (delayErrors) {
// 如果是延迟错误处理,将错误信息暂存
error = ExceptionHelper.addThrowable(error, t);
} else {
for (Disposable d : sources) {
d.dispose();
}
sources.clear();
actual.onError(t);
}
}
@Override
public void onComplete() {
if (sources.remove(this)) {
// 移除当前完成的Observable对应的Disposable
drain();
}
}
void drain() {
if (wip != 0 ||!QueueDisposableHelper.openSubscription(this, queue)) {
return;
}
int missed = 1;
final Observer<? super T> a = actual;
final List<Disposable> sources = this.sources;
final Queue<T> q = queue;
for (;;) {
for (; ; ) {
boolean d = done;
T v;
try {
v = q.poll();
} catch (Throwable ex) {
for (Disposable s : sources) {
s.dispose();
}
sources.clear();
q.clear();
a.onError(ex);
return;
}
boolean empty = v == null;
if (checkTerminated(d, empty, a)) {
return;
}
if (empty) {
break;
}
// 将队列中的数据发送给下游Observer
a.onNext(v);
}
missed = wip - missed;
if (missed == 0) {
break;
}
wip = 0;
}
}
boolean checkTerminated(boolean d, boolean empty, Observer<? super T> a) {
if (d) {
if (delayErrors) {
if (error != null) {
a.onError(error);
} else {
a.onComplete();
}
} else if (empty) {
Throwable e = error;
if (e != null) {
a.onError(e);
} else {
a.onComplete();
}
}
return true;
}
return false;
}
@Override
public void dispose() {
// 取消所有相关的订阅
s.dispose();
for (Disposable d : sources) {
d.dispose();
}
sources.clear();
queue.clear();
}
@Override
public boolean isDisposed() {
return s.isDisposed();
}
@Override
public void run() {
drain();
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public T poll() throws Exception {
return queue.poll();
}
@Override
public boolean isEmpty() {
return queue.isEmpty();
}
@Override
public void clear() {
queue.clear();
}
}
subscribeActual
方法中,MergeObserver
会遍历传入的所有 Observable
,并为每个 Observable
创建一个 InnerObserver
进行订阅。同时,将这些 Observable
对应的 Disposable
存储在 sources
列表中。Observable
发出数据时,MergeObserver
的 onNext
方法会将数据存入 queue
队列中,然后调用 drain
方法处理队列中的数据。drain
方法会不断从 queue
队列中取出数据,并将其发送给下游的 Observer
。如果在处理过程中所有 Observable
都完成(done
为 true
)且队列中没有数据(empty
为 true
),则会根据是否延迟错误处理(delayErrors
)来决定是发出错误信号还是完成信号。Observable
发出错误信号,MergeObserver
的 onError
方法会根据 delayErrors
的设置来处理错误。如果是延迟错误处理,会将错误信息暂存,直到所有 Observable
都完成后再统一处理;否则会立即取消所有订阅并将错误信号发送给下游 Observer
。dispose
方法时,MergeObserver
会取消所有相关 Observable
的订阅,并清空 sources
列表和 queue
队列。concat()
操作符与 merge()
类似,也是用于合并多个 Observable
,但不同的是,concat()
会按照传入 Observable
的顺序依次订阅并发送数据,只有当前一个 Observable
完成后,才会开始订阅并接收下一个 Observable
发出的数据。
import io.reactivex.Observable;
// 创建两个Observable对象
Observable<Integer> observable1 = Observable.just(1, 2, 3);
Observable<Integer> observable2 = Observable.just(4, 5, 6);
// 使用concat()操作符合并两个Observable
Observable<Integer> concatenatedObservable = Observable.concat(observable1, observable2);
// 订阅合并后的Observable并打印接收到的数据
concatenatedObservable.subscribe(System.out::println);
在上述代码中,下游 Observer
会先收到 observable1
发出的 1, 2, 3
,等 observable1
完成后,再收到 observable2
发出的 4, 5, 6
。
concat()
方法有多个重载版本,以下是接收多个 Observable
参数的版本源码:
@SafeVarargs
public static <T> Observable<T> concat(ObservableSource<? extends T>... sources) {
// 检查传入的Observable数组是否为null
ObjectHelper.requireNonNull(sources, "sources is null");
// 如果只有一个Observable,直接返回该Observable
if (sources.length == 1) {
@SuppressWarnings("unchecked")
ObservableSource<T> s = (ObservableSource<T>)sources[0];
return RxJavaPlugins.onAssembly((Observable<T>)s);
}
// 创建一个ObservableConcatArray对象,将多个Observable作为参数传入
return RxJavaPlugins.onAssembly(new ObservableConcatArray<>(sources));
}
该方法首先对传入的 Observable
数组进行非空校验。如果数组只有一个元素,直接返回该元素对应的 Observable
;否则创建 ObservableConcatArray
实例,并通过 RxJavaPlugins.onAssembly()
方法进行全局组装。
ObservableConcatArray
类继承自 Observable
,其核心代码如下:
public final class ObservableConcatArray<T> extends Observable<T> {
final ObservableSource<? extends T>[] sources;
@SafeVarargs
public ObservableConcatArray(ObservableSource<? extends T>... sources) {
this.sources = sources;
}
@Override
public void subscribeActual(Observer<? super T> observer) {
// 创建一个ConcatArrayObserver实例,用于处理合并逻辑
ConcatArrayObserver<T> parent = new ConcatArrayObserver<>(observer, sources);
observer.onSubscribe(parent);
parent.subscribeNext();
}
static final class ConcatArrayObserver<T> extends AtomicInteger implements Disposable, Observer<T> {
private static final long serialVersionUID = -8158322871608889516L;
final Observer<? super T> actual;
final ObservableSource<? extends T>[] sources;
int index;
boolean done;
Disposable s;
ConcatArrayObserver(Observer<? super T> actual, ObservableSource<? extends T>[] sources) {
this.actual = actual;
this.sources = sources;
}
@Override
public void onSubscribe(Disposable s) {
this.s = s;
}
@Override
public void onNext(T t) {
actual.onNext(t);
}
@Override
public void onError(Throwable t) {
done = true;
actual.onError(t);
}
@Override
public void onComplete() {
subscribeNext();
}
void subscribeNext() {
if (done) {
return;
}
if (getAndIncrement() != 0) {
return;
}
int n = sources.length;
for (; ; ) {
if (isDisposed()) {
return;
}
int idx = index;
if (idx == n) {
done = true;
actual.onComplete();
return;
}
ObservableSource<? extends T> source = sources[idx];
if (source == null) {
Throwable e = new NullPointerException("sources[" + idx + "] is null");
done = true;
actual.onError(e);
return;
}
source.subscribe(this);
index = idx + 1;
if (decrementAndGet() == 0) {
return;
}
}
}
@Override
public void dispose() {
s.dispose();
}
@Override
public boolean isDisposed() {
return s.isDisposed();
}
}
}
subscribeActual
方法中,ObservableConcatArray
会创建一个 ConcatArrayObserver
实例,并调用 subscribeNext
方法开始订阅第一个 Observable
。Observable
发出数据时,ConcatArrayObserver
的 onNext
方法会将数据直接发送给下游 Observer
。Observable
阶段:当当前 Observable
完成时,ConcatArrayObserver
的 onComplete
方法会调用 subscribeNext
方法,开始订阅下一个 Observable
。Observable
发出错误信号,ConcatArrayObserver
的 onError
方法会将错误信号直接发送给下游 Observer
,并标记为完成。dispose
方法时,ConcatArrayObserver
会取消当前 Observable
的订阅。通过以上分析,可以看出 merge()
和 concat()
操作符虽然都用于合并多个 Observable
,但在处理数据的顺序和方式上有所不同,开发者可以根据具体需求选择合适的操作符。
zip()
操作符用于将多个 Observable
发出的数据项按照索引位置进行配对组合,然后将组合后的数据发送给下游 Observer
。当其中一个 Observable
完成且没有更多数据发出时,zip()
操作符就会停止工作并发出完成信号。
以下是一个简单的示例代码:
import io.reactivex.Observable;
import io.reactivex.functions.BiFunction;
// 创建两个 Observable 对象
Observable<Integer> observable1 = Observable.just(1, 2, 3);
Observable<String> observable2 = Observable.just("A", "B", "C");
// 使用 zip() 操作符将两个 Observable 进行配对组合
Observable<String> zippedObservable = Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return integer + s;
}
});
// 订阅组合后的 Observable 并打印接收到的数据
zippedObservable.subscribe(System.out::println);
在上述代码中,zip()
操作符将 observable1
和 observable2
发出的数据进行配对组合,最终下游 Observer
会收到 1A
、2B
、3C
。
zip()
方法有多个重载版本,这里分析接收两个 Observable
参数的版本:
public static <T1, T2, R> Observable<R> zip(
ObservableSource<? extends T1> source1, ObservableSource<? extends T2> source2,
BiFunction<? super T1, ? super T2, ? extends R> zipper) {
// 检查参数是否为 null
ObjectHelper.requireNonNull(source1, "source1 is null");
ObjectHelper.requireNonNull(source2, "source2 is null");
ObjectHelper.requireNonNull(zipper, "zipper is null");
// 创建一个 ObservableZip 对象,将两个 Observable 和组合函数作为参数传入
return RxJavaPlugins.onAssembly(new ObservableZip<>(new ObservableSource<?>[] { source1, source2 }, zipper));
}
该方法首先对传入的两个 Observable
和组合函数 zipper
进行非空校验,然后创建 ObservableZip
实例,并通过 RxJavaPlugins.onAssembly()
方法进行全局组装。
ObservableZip
类继承自 Observable
,其核心代码如下:
public final class ObservableZip<T, R> extends Observable<R> {
final ObservableSource<? extends T>[] sources;
final Function<? super Object[], ? extends R> zipper;
public ObservableZip(ObservableSource<? extends T>[] sources, Function<? super Object[], ? extends R> zipper) {
this.sources = sources;
this.zipper = zipper;
}
@Override
public void subscribeActual(Observer<? super R> observer) {
// 创建一个 ZipCoordinator 实例,用于协调多个 Observable 的数据配对组合
ZipCoordinator<T, R> zc = new ZipCoordinator<>(observer, sources.length, zipper);
observer.onSubscribe(zc);
for (int i = 0; i < sources.length; i++) {
ObservableSource<? extends T> source = sources[i];
if (source == null) {
// 如果有 Observable 为 null,发出错误信号
zc.innerError(new NullPointerException("source at index " + i + " is null"), i);
return;
}
// 为每个 Observable 创建一个 ZipObserver 并进行订阅
source.subscribe(new ZipObserver<>(zc, i));
}
}
static final class ZipCoordinator<T, R> extends AtomicInteger implements Disposable {
private static final long serialVersionUID = 2983708048395377667L;
final Observer<? super R> actual;
final Function<? super Object[], ? extends R> zipper;
final ZipObserver<T>[] observers;
final Object[] row;
final AtomicInteger active;
final AtomicBoolean cancelled;
final AtomicReference<Throwable> error;
final int size;
@SuppressWarnings("unchecked")
ZipCoordinator(Observer<? super R> actual, int n, Function<? super Object[], ? extends R> zipper) {
this.actual = actual;
this.zipper = zipper;
this.size = n;
this.observers = new ZipObserver[n];
this.row = new Object[n];
this.active = new AtomicInteger(n);
this.cancelled = new AtomicBoolean();
this.error = new AtomicReference<>();
}
@Override
public void dispose() {
if (cancelled.compareAndSet(false, true)) {
for (ZipObserver<T> observer : observers) {
observer.dispose();
}
}
}
@Override
public boolean isDisposed() {
return cancelled.get();
}
void innerNext(T value, int index) {
if (!cancelled.get()) {
row[index] = value;
if (active.decrementAndGet() == 0) {
try {
// 使用组合函数将配对的数据进行组合
R v = zipper.apply(row);
if (v == null) {
throw new NullPointerException("The zipper returned a null value.");
}
// 将组合后的数据发送给下游 Observer
actual.onNext(v);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
innerError(ex, index);
return;
}
for (int i = 0; i < size; i++) {
observers[i].take();
}
active.lazySet(size);
}
}
}
void innerError(Throwable e, int index) {
if (cancelled.compareAndSet(false, true)) {
for (int i = 0; i < size; i++) {
if (i != index) {
observers[i].dispose();
}
}
error.lazySet(e);
actual.onError(e);
} else {
RxJavaPlugins.onError(e);
}
}
void innerComplete(int index) {
if (!cancelled.get()) {
observers[index].done = true;
if (checkTerminate()) {
return;
}
}
}
boolean checkTerminate() {
if (cancelled.get()) {
return true;
}
Throwable ex = error.get();
if (ex != null) {
for (ZipObserver<T> observer : observers) {
observer.dispose();
}
actual.onError(ex);
return true;
}
for (ZipObserver<T> observer : observers) {
if (!observer.done) {
return false;
}
}
actual.onComplete();
return true;
}
}
static final class ZipObserver<T> extends AtomicReference<Disposable> implements Observer<T> {
private static final long serialVersionUID = 3323743579927613702L;
final ZipCoordinator<T, ?> parent;
final int index;
final SpscLinkedArrayQueue<T> queue;
boolean done;
ZipObserver(ZipCoordinator<T, ?> parent, int index) {
this.parent = parent;
this.index = index;
this.queue = new SpscLinkedArrayQueue<>(QueueDisposable.bufferSize());
}
@Override
public void onSubscribe(Disposable s) {
DisposableHelper.setOnce(this, s);
parent.observers[index] = this;
}
@Override
public void onNext(T t) {
if (!done) {
queue.offer(t);
parent.innerNext(t, index);
}
}
@Override
public void onError(Throwable t) {
if (!done) {
done = true;
parent.innerError(t, index);
} else {
RxJavaPlugins.onError(t);
}
}
@Override
public void onComplete() {
if (!done) {
done = true;
parent.innerComplete(index);
}
}
void take() {
T v = queue.poll();
if (v != null) {
parent.innerNext(v, index);
}
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
}
subscribeActual
方法中,ObservableZip
会创建一个 ZipCoordinator
实例,用于协调多个 Observable
的数据配对组合。然后为每个 Observable
创建一个 ZipObserver
并进行订阅。Observable
发出数据时,对应的 ZipObserver
的 onNext
方法会将数据存入队列,并调用 ZipCoordinator
的 innerNext
方法。ZipCoordinator
的 innerNext
方法中,会将接收到的数据存入 row
数组。当所有 Observable
都有数据到达时(active
计数器减为 0),会使用组合函数 zipper
将 row
数组中的数据进行组合,并将组合后的数据发送给下游 Observer
。Observable
发出错误信号,对应的 ZipObserver
的 onError
方法会调用 ZipCoordinator
的 innerError
方法,该方法会取消所有 Observable
的订阅,并将错误信号发送给下游 Observer
。Observable
完成时,对应的 ZipObserver
的 onComplete
方法会调用 ZipCoordinator
的 innerComplete
方法。ZipCoordinator
会检查是否所有 Observable
都已完成,如果是,则发出完成信号。dispose
方法时,ZipCoordinator
会取消所有 Observable
的订阅。combineLatest()
操作符会将多个 Observable
最新发出的数据项进行组合,然后将组合后的数据发送给下游 Observer
。只要其中一个 Observable
发出新的数据,就会立即与其他 Observable
最新发出的数据进行组合并发送。
以下是一个简单的示例代码:
import io.reactivex.Observable;
import io.reactivex.functions.BiFunction;
// 创建两个 Observable 对象
Observable<Integer> observable1 = Observable.just(1, 2, 3);
Observable<String> observable2 = Observable.just("A", "B", "C");
// 使用 combineLatest() 操作符将两个 Observable 进行组合
Observable<String> combinedObservable = Observable.combineLatest(observable1, observable2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return integer + s;
}
});
// 订阅组合后的 Observable 并打印接收到的数据
combinedObservable.subscribe(System.out::println);
在上述代码中,combineLatest()
操作符会将 observable1
和 observable2
最新发出的数据进行组合,最终下游 Observer
会收到组合后的数据。
combineLatest()
方法有多个重载版本,这里分析接收两个 Observable
参数的版本:
public static <T1, T2, R> Observable<R> combineLatest(
ObservableSource<? extends T1> source1, ObservableSource<? extends T2> source2,
BiFunction<? super T1, ? super T2, ? extends R> combiner) {
// 检查参数是否为 null
ObjectHelper.requireNonNull(source1, "source1 is null");
ObjectHelper.requireNonNull(source2, "source2 is null");
ObjectHelper.requireNonNull(combiner, "combiner is null");
// 创建一个 ObservableCombineLatest 对象,将两个 Observable 和组合函数作为参数传入
return RxJavaPlugins.onAssembly(new ObservableCombineLatest<>(new ObservableSource<?>[] { source1, source2 }, combiner));
}
该方法首先对传入的两个 Observable
和组合函数 combiner
进行非空校验,然后创建 ObservableCombineLatest
实例,并通过 RxJavaPlugins.onAssembly()
方法进行全局组装。
ObservableCombineLatest
类继承自 Observable
,其核心代码如下:
public final class ObservableCombineLatest<T, R> extends Observable<R> {
final ObservableSource<? extends T>[] sources;
final Function<? super Object[], ? extends R> combiner;
public ObservableCombineLatest(ObservableSource<? extends T>[] sources, Function<? super Object[], ? extends R> combiner) {
this.sources = sources;
this.combiner = combiner;
}
@Override
public void subscribeActual(Observer<? super R> observer) {
// 创建一个 CombineLatestCoordinator 实例,用于协调多个 Observable 的数据组合
CombineLatestCoordinator<T, R> clc = new CombineLatestCoordinator<>(observer, combiner, sources.length);
observer.onSubscribe(clc);
for (int i = 0; i < sources.length; i++) {
ObservableSource<? extends T> source = sources[i];
if (source == null) {
// 如果有 Observable 为 null,发出错误信号
clc.innerError(new NullPointerException("source at index " + i + " is null"), i);
return;
}
// 为每个 Observable 创建一个 CombineLatestObserver 并进行订阅
source.subscribe(new CombineLatestObserver<>(clc, i));
}
}
static final class CombineLatestCoordinator<T, R> extends AtomicInteger implements Disposable {
private static final long serialVersionUID = -5586979301535943796L;
final Observer<? super R> actual;
final Function<? super Object[], ? extends R> combiner;
final CombineLatestObserver<T>[] observers;
final Object[] latest;
final AtomicInteger active;
final AtomicBoolean cancelled;
final AtomicReference<Throwable> error;
final int size;
@SuppressWarnings("unchecked")
CombineLatestCoordinator(Observer<? super R> actual, Function<? super Object[], ? extends R> combiner, int n) {
this.actual = actual;
this.combiner = combiner;
this.size = n;
this.observers = new CombineLatestObserver[n];
this.latest = new Object[n];
this.active = new AtomicInteger(n);
this.cancelled = new AtomicBoolean();
this.error = new AtomicReference<>();
}
@Override
public void dispose() {
if (cancelled.compareAndSet(false, true)) {
for (CombineLatestObserver<T> observer : observers) {
observer.dispose();
}
}
}
@Override
public boolean isDisposed() {
return cancelled.get();
}
void innerNext(T value, int index) {
if (!cancelled.get()) {
latest[index] = value;
if (active.get() == 0) {
try {
// 使用组合函数将最新的数据进行组合
R v = combiner.apply(latest);
if (v == null) {
throw new NullPointerException("The combiner returned a null value.");
}
// 将组合后的数据发送给下游 Observer
actual.onNext(v);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
innerError(ex, index);
return;
}
}
}
}
void innerError(Throwable e, int index) {
if (cancelled.compareAndSet(false, true)) {
for (int i = 0; i < size; i++) {
if (i != index) {
observers[i].dispose();
}
}
error.lazySet(e);
actual.onError(e);
} else {
RxJavaPlugins.onError(e);
}
}
void innerComplete(int index) {
if (!cancelled.get()) {
observers[index].done = true;
if (checkTerminate()) {
return;
}
}
}
boolean checkTerminate() {
if (cancelled.get()) {
return true;
}
Throwable ex = error.get();
if (ex != null) {
for (CombineLatestObserver<T> observer : observers) {
observer.dispose();
}
actual.onError(ex);
return true;
}
for (CombineLatestObserver<T> observer : observers) {
if (!observer.done) {
return false;
}
}
actual.onComplete();
return true;
}
}
static final class CombineLatestObserver<T> extends AtomicReference<Disposable> implements Observer<T> {
private static final long serialVersionUID = 3323743579927613702L;
final CombineLatestCoordinator<T, ?> parent;
final int index;
boolean done;
CombineLatestObserver(CombineLatestCoordinator<T, ?> parent, int index) {
this.parent = parent;
this.index = index;
}
@Override
public void onSubscribe(Disposable s) {
DisposableHelper.setOnce(this, s);
parent.observers[index] = this;
}
@Override
public void onNext(T t) {
if (!done) {
parent.innerNext(t, index);
}
}
@Override
public void onError(Throwable t) {
if (!done) {
done = true;
parent.innerError(t, index);
} else {
RxJavaPlugins.onError(t);
}
}
@Override
public void onComplete() {
if (!done) {
done = true;
parent.innerComplete(index);
}
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
}
subscribeActual
方法中,ObservableCombineLatest
会创建一个 CombineLatestCoordinator
实例,用于协调多个 Observable
的数据组合。然后为每个 Observable
创建一个 CombineLatestObserver
并进行订阅。Observable
发出数据时,对应的 CombineLatestObserver
的 onNext
方法会调用 CombineLatestCoordinator
的 innerNext
方法。CombineLatestCoordinator
的 innerNext
方法中,会将接收到的数据存入 latest
数组。当所有 Observable
都至少发出过一次数据时(active
计数器为 0),会使用组合函数 combiner
将 latest
数组中的最新数据进行组合,并将组合后的数据发送给下游 Observer
。Observable
发出错误信号,对应的 CombineLatestObserver
的 onError
方法会调用 CombineLatestCoordinator
的 innerError
方法,该方法会取消所有 Observable
的订阅,并将错误信号发送给下游 Observer
。Observable
完成时,对应的 CombineLatestObserver
的 onComplete
方法会调用 CombineLatestCoordinator
的 innerComplete
方法。CombineLatestCoordinator
会检查是否所有 Observable
都已完成,如果是,则发出完成信号。dispose
方法时,CombineLatestCoordinator
会取消所有 Observable
的订阅。通过以上分析,可以看出 zip()
和 combineLatest()
操作符虽然都用于组合多个 Observable
的数据,但在组合方式上有所不同。zip()
是按索引位置配对组合,而 combineLatest()
是将最新的数据进行组合。开发者可以根据具体需求选择合适的操作符。
onErrorReturn()
操作符允许你在 Observable
遇到错误时,返回一个预设的默认值,而不是直接将错误传递给下游的 Observer
。这样可以让 Observable
以一种更优雅的方式处理错误,避免程序崩溃。
以下是示例代码:
import io.reactivex.Observable;
import io.reactivex.functions.Function;
// 创建一个可能会抛出异常的 Observable
Observable<Integer> observable = Observable.create(emitter -> {
for (int i = 0; i < 5; i++) {
if (i == 3) {
// 模拟发生错误
emitter.onError(new RuntimeException("Error at index 3"));
} else {
emitter.onNext(i);
}
}
emitter.onComplete();
});
// 使用 onErrorReturn() 操作符处理错误
Observable<Integer> errorHandledObservable = observable.onErrorReturn(new Function<Throwable, Integer>() {
@Override
public Integer apply(Throwable throwable) throws Exception {
// 当发生错误时,返回默认值 -1
return -1;
}
});
// 订阅处理后的 Observable 并打印接收到的数据
errorHandledObservable.subscribe(
value -> System.out.println("Received: " + value),
error -> System.out.println("Error: " + error.getMessage()),
() -> System.out.println("Completed")
);
在上述代码中,当 Observable
在 i = 3
时抛出异常,onErrorReturn()
操作符会捕获该异常,并返回预设的默认值 -1
给下游的 Observer
。
onErrorReturn()
方法在 Observable
类中定义如下:
public final Observable<T> onErrorReturn(Function<? super Throwable, ? extends T> valueSupplier) {
// 检查传入的 valueSupplier 是否为 null
ObjectHelper.requireNonNull(valueSupplier, "valueSupplier is null");
// 创建一个 ObservableOnErrorReturn 对象,将当前 Observable 和 valueSupplier 作为参数传入
return RxJavaPlugins.onAssembly(new ObservableOnErrorReturn<T>(this, valueSupplier));
}
此方法先对传入的 valueSupplier
进行非空校验,接着创建 ObservableOnErrorReturn
实例,并通过 RxJavaPlugins.onAssembly()
方法进行全局组装。
ObservableOnErrorReturn
类继承自 AbstractObservableWithUpstream
,其核心代码如下:
public final class ObservableOnErrorReturn<T> extends AbstractObservableWithUpstream<T, T> {
final Function<? super Throwable, ? extends T> valueSupplier;
public ObservableOnErrorReturn(ObservableSource<T> source, Function<? super Throwable, ? extends T> valueSupplier) {
super(source);
this.valueSupplier = valueSupplier;
}
@Override
public void subscribeActual(Observer<? super T> s) {
// 创建一个 OnErrorReturnObserver 实例,用于处理错误并返回默认值
source.subscribe(new OnErrorReturnObserver<T>(s, valueSupplier));
}
static final class OnErrorReturnObserver<T> extends BasicFuseableObserver<T, T> {
private static final long serialVersionUID = -3740826063558713822L;
final Function<? super Throwable, ? extends T> valueSupplier;
OnErrorReturnObserver(Observer<? super T> actual, Function<? super Throwable, ? extends T> valueSupplier) {
super(actual);
this.valueSupplier = valueSupplier;
}
@Override
public void onError(Throwable t) {
T v;
try {
// 调用 valueSupplier 获取默认值
v = valueSupplier.apply(t);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
actual.onError(new CompositeException(t, ex));
return;
}
if (v == null) {
NullPointerException npe = new NullPointerException("The supplied value is null");
npe.initCause(t);
actual.onError(npe);
return;
}
// 将默认值发送给下游 Observer
actual.onNext(v);
actual.onComplete();
}
@Override
public void onNext(T t) {
if (!done) {
actual.onNext(t);
}
}
@Override
public void onComplete() {
if (!done) {
actual.onComplete();
}
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public T poll() throws Exception {
return qs.poll();
}
}
}
在 ObservableOnErrorReturn
类中,subscribeActual
方法创建 OnErrorReturnObserver
实例来处理订阅逻辑。OnErrorReturnObserver
类的 onError
方法在接收到上游 Observable
的错误信号时,会调用 valueSupplier
函数获取预设的默认值。若获取默认值过程中出现异常,会将原错误和新异常组合后发送给下游 Observer
。若默认值不为 null
,则将该默认值发送给下游 Observer
并发出完成信号。
onErrorResumeNext()
操作符在 Observable
遇到错误时,会切换到另一个 Observable
继续发送数据,而不是将错误传递给下游 Observer
。
以下是示例代码:
import io.reactivex.Observable;
import io.reactivex.functions.Function;
// 创建一个可能会抛出异常的 Observable
Observable<Integer> observable = Observable.create(emitter -> {
for (int i = 0; i < 5; i++) {
if (i == 3) {
// 模拟发生错误
emitter.onError(new RuntimeException("Error at index 3"));
} else {
emitter.onNext(i);
}
}
emitter.onComplete();
});
// 创建一个备用的 Observable
Observable<Integer> fallbackObservable = Observable.just(10, 11, 12);
// 使用 onErrorResumeNext() 操作符处理错误
Observable<Integer> errorResumedObservable = observable.onErrorResumeNext(new Function<Throwable, ObservableSource<? extends Integer>>() {
@Override
public ObservableSource<? extends Integer> apply(Throwable throwable) throws Exception {
// 当发生错误时,返回备用的 Observable
return fallbackObservable;
}
});
// 订阅处理后的 Observable 并打印接收到的数据
errorResumedObservable.subscribe(
value -> System.out.println("Received: " + value),
error -> System.out.println("Error: " + error.getMessage()),
() -> System.out.println("Completed")
);
在上述代码中,当 Observable
在 i = 3
时抛出异常,onErrorResumeNext()
操作符会捕获该异常,并切换到 fallbackObservable
继续发送数据给下游 Observer
。
onErrorResumeNext()
方法在 Observable
类中定义如下:
public final Observable<T> onErrorResumeNext(Function<? super Throwable, ? extends ObservableSource<? extends T>> nextSupplier) {
// 检查传入的 nextSupplier 是否为 null
ObjectHelper.requireNonNull(nextSupplier, "nextSupplier is null");
// 创建一个 ObservableOnErrorResumeNextViaFunction 对象,将当前 Observable 和 nextSupplier 作为参数传入
return RxJavaPlugins.onAssembly(new ObservableOnErrorResumeNextViaFunction<T>(this, nextSupplier));
}
该方法先对 nextSupplier
进行非空校验,然后创建 ObservableOnErrorResumeNextViaFunction
实例,并通过 RxJavaPlugins.onAssembly()
方法进行全局组装。
ObservableOnErrorResumeNextViaFunction
类继承自 AbstractObservableWithUpstream
,其核心代码如下:
public final class ObservableOnErrorResumeNextViaFunction<T> extends AbstractObservableWithUpstream<T, T> {
final Function<? super Throwable, ? extends ObservableSource<? extends T>> nextSupplier;
public ObservableOnErrorResumeNextViaFunction(ObservableSource<T> source, Function<? super Throwable, ? extends ObservableSource<? extends T>> nextSupplier) {
super(source);
this.nextSupplier = nextSupplier;
}
@Override
public void subscribeActual(Observer<? super T> s) {
// 创建一个 OnErrorResumeNextObserver 实例,用于处理错误并切换到备用 Observable
OnErrorResumeNextObserver<T> parent = new OnErrorResumeNextObserver<T>(s, nextSupplier);
s.onSubscribe(parent);
source.subscribe(parent);
}
static final class OnErrorResumeNextObserver<T> extends AtomicInteger implements Observer<T>, Disposable {
private static final long serialVersionUID = -4603919676453758899L;
final Observer<? super T> actual;
final Function<? super Throwable, ? extends ObservableSource<? extends T>> nextSupplier;
Disposable s;
ObservableSource<? extends T> next;
boolean done;
OnErrorResumeNextObserver(Observer<? super T> actual, Function<? super Throwable, ? extends ObservableSource<? extends T>> nextSupplier) {
this.actual = actual;
this.nextSupplier = nextSupplier;
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.validate(this.s, s)) {
this.s = s;
actual.onSubscribe(this);
}
}
@Override
public void onNext(T t) {
if (!done) {
actual.onNext(t);
}
}
@Override
public void onError(Throwable t) {
if (done) {
RxJavaPlugins.onError(t);
return;
}
done = true;
ObservableSource<? extends T> nextSource;
try {
// 调用 nextSupplier 获取备用的 Observable
nextSource = nextSupplier.apply(t);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
actual.onError(new CompositeException(t, ex));
return;
}
if (nextSource == null) {
NullPointerException npe = new NullPointerException("The next Observable is null");
npe.initCause(t);
actual.onError(npe);
return;
}
// 订阅备用的 Observable
nextSource.subscribe(new InnerObserver());
}
@Override
public void onComplete() {
if (!done) {
done = true;
actual.onComplete();
}
}
@Override
public void dispose() {
s.dispose();
if (next != null) {
next.subscribe(new DisposeObserver());
}
}
@Override
public boolean isDisposed() {
return s.isDisposed();
}
final class InnerObserver implements Observer<T> {
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.setOnce(OnErrorResumeNextObserver.this.s, s)) {
next = null;
OnErrorResumeNextObserver.this.lazySet(0);
}
}
@Override
public void onNext(T t) {
actual.onNext(t);
}
@Override
public void onError(Throwable t) {
actual.onError(t);
}
@Override
public void onComplete() {
actual.onComplete();
}
}
final class DisposeObserver implements Observer<T> {
@Override
public void onSubscribe(Disposable s) {
s.dispose();
}
@Override
public void onNext(T t) {
// 忽略数据
}
@Override
public void onError(Throwable t) {
// 忽略错误
}
@Override
public void onComplete() {
// 忽略完成信号
}
}
}
}
在 ObservableOnErrorResumeNextViaFunction
类中,subscribeActual
方法创建 OnErrorResumeNextObserver
实例来处理订阅逻辑。OnErrorResumeNextObserver
类的 onError
方法在接收到上游 Observable
的错误信号时,会调用 nextSupplier
函数获取备用的 Observable
。若获取备用 Observable
过程中出现异常,会将原错误和新异常组合后发送给下游 Observer
。若备用 Observable
不为 null
,则订阅该备用 Observable
并继续发送数据给下游 Observer
。
retry()
操作符会在 Observable
遇到错误时,重新订阅该 Observable
,尝试再次发送数据,直到达到指定的重试次数或者不再出现错误。
以下是示例代码:
import io.reactivex.Observable;
import java.util.concurrent.TimeUnit;
// 创建一个可能会抛出异常的 Observable
Observable<Integer> observable = Observable.create(emitter -> {
for (int i = 0; i < 5; i++) {
if (i == 3) {
// 模拟发生错误
emitter.onError(new RuntimeException("Error at index 3"));
} else {
emitter.onNext(i);
}
}
emitter.onComplete();
});
// 使用 retry() 操作符进行重试,最多重试 2 次
Observable<Integer> retriedObservable = observable.retry(2);
// 订阅处理后的 Observable 并打印接收到的数据
retriedObservable.subscribe(
value -> System.out.println("Received: " + value),
error -> System.out.println("Error: " + error.getMessage()),
() -> System.out.println("Completed")
);
在上述代码中,当 Observable
在 i = 3
时抛出异常,retry()
操作符会重新订阅该 Observable
最多 2 次,若重试 2 次后仍然出现错误,则将错误传递给下游 Observer
。
retry()
方法在 Observable
类中有多个重载版本,这里分析接收重试次数参数的版本:
public final Observable<T> retry(long times) {
// 检查重试次数是否合法
if (times < 0) {
throw new IllegalArgumentException("times >= 0 required but it was " + times);
}
// 创建一个 ObservableRetryBiPredicate 对象,将当前 Observable 和重试次数作为参数传入
return retry(new BiPredicate<Long, Throwable>() {
long current;
@Override
public boolean test(Long t1, Throwable t2) throws Exception {
return ++current <= times;
}
});
}
该方法先对重试次数进行合法性校验,确保其大于等于 0。然后创建一个 BiPredicate
函数,用于判断是否继续重试。最后调用重载的 retry()
方法,传入该 BiPredicate
函数。
重载的 retry()
方法定义如下:
public final Observable<T> retry(BiPredicate<? super Long, ? super Throwable> predicate) {
// 检查传入的 predicate 是否为 null
ObjectHelper.requireNonNull(predicate, "predicate is null");
// 创建一个 ObservableRetryPredicate 对象,将当前 Observable 和 predicate 作为参数传入
return RxJavaPlugins.onAssembly(new ObservableRetryPredicate<T>(this, predicate));
}
此方法对 predicate
进行非空校验,然后创建 ObservableRetryPredicate
实例,并通过 RxJavaPlugins.onAssembly()
方法进行全局组装。
ObservableRetryPredicate
类继承自 AbstractObservableWithUpstream
,其核心代码如下:
public final class ObservableRetryPredicate<T> extends AbstractObservableWithUpstream<T, T> {
final BiPredicate<? super Long, ? super Throwable> predicate;
public ObservableRetryPredicate(ObservableSource<T> source, BiPredicate<? super Long, ? super Throwable> predicate) {
super(source);
this.predicate = predicate;
}
@Override
public void subscribeActual(Observer<? super T> s) {
// 创建一个 RetryObserver 实例,用于处理重试逻辑
RetryObserver<T> parent = new RetryObserver<T>(s, predicate, source);
s.onSubscribe(parent);
parent.subscribeNext();
}
static final class RetryObserver<T> extends AtomicInteger implements Observer<T>, Disposable {
private static final long serialVersionUID = -7098360935104053232L;
final Observer<? super T> actual;
final BiPredicate<? super Long, ? super Throwable> predicate;
final ObservableSource<T> source;
Disposable s;
long retries;
RetryObserver(Observer<? super T> actual, BiPredicate<? super Long, ? super Throwable> predicate, ObservableSource<T> source) {
this.actual = actual;
this.predicate = predicate;
this.source = source;
}
@Override
public void onSubscribe(Disposable s) {
this.s = s;
}
@Override
public void onNext(T t) {
retries = 0;
actual.onNext(t);
}
@Override
public void onError(Throwable t) {
try {
boolean b;
// 调用 predicate 判断是否继续重试
b = predicate.test(++retries, t);
if (b) {
// 若需要重试,重新订阅 Observable
subscribeNext();
} else {
actual.onError(t);
}
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
actual.onError(new CompositeException(t, ex));
}
}
@Override
public void onComplete() {
actual.onComplete();
}
@Override
public void dispose() {
s.dispose();
}
@Override
public boolean isDisposed() {
return s.isDisposed();
}
void subscribeNext() {
if (getAndIncrement() == 0) {
int missed = 1;
for (; ; ) {
if (isDisposed()) {
return;
}
// 重新订阅 Observable
source.subscribe(this);
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
}
}
}
在 ObservableRetryPredicate
类中,subscribeActual
方法创建 RetryObserver
实例来处理订阅逻辑。RetryObserver
类的 onError
方法在接收到上游 Observable
的错误信号时,会调用 predicate
函数判断是否继续重试。若需要重试,则调用 subscribeNext
方法重新订阅 Observable
;若不需要重试,则将错误传递给下游 Observer
。
通过以上对错误处理操作符的分析,我们可以看到 RxJava 提供了多种方式来处理 Observable
中出现的错误,开发者可以根据具体需求选择合适的操作符来增强程序的健壮性。
在 RxJava 里,调度器(Schedulers)的作用是决定任务在哪个线程执行。借助调度器,你能够控制 Observable
发射数据、Observer
接收数据的线程。这在处理耗时操作或者进行多线程编程时极为关键。
Schedulers.io()
适用于 I/O 密集型任务,像网络请求、文件读写等。它会维护一个线程池,线程数量会根据需求动态调整。
以下是示例代码:
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
// 创建一个 Observable
Observable<Integer> observable = Observable.range(1, 5);
// 使用 Schedulers.io() 调度器
observable.subscribeOn(Schedulers.io())
.subscribe(value -> {
System.out.println("Received: " + value + " on thread: " + Thread.currentThread().getName());
});
在上述代码中,subscribeOn(Schedulers.io())
让 Observable
的数据发射操作在 io()
调度器的线程池里执行。
Schedulers.computation()
用于 CPU 密集型任务,例如数据计算、图像处理等。它所维护的线程池大小与 CPU 核心数相同。
以下是示例代码:
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
// 创建一个 Observable
Observable<Integer> observable = Observable.range(1, 5);
// 使用 Schedulers.computation() 调度器
observable.subscribeOn(Schedulers.computation())
.subscribe(value -> {
System.out.println("Received: " + value + " on thread: " + Thread.currentThread().getName());
});
这里,subscribeOn(Schedulers.computation())
使 Observable
的数据发射操作在 computation()
调度器的线程池里执行。
Schedulers.single()
拥有一个单线程的线程池,所有任务都会按顺序在这个线程上执行。
以下是示例代码:
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
// 创建一个 Observable
Observable<Integer> observable = Observable.range(1, 5);
// 使用 Schedulers.single() 调度器
observable.subscribeOn(Schedulers.single())
.subscribe(value -> {
System.out.println("Received: " + value + " on thread: " + Thread.currentThread().getName());
});
在这个例子中,subscribeOn(Schedulers.single())
让 Observable
的数据发射操作在 single()
调度器的单线程上执行。
在 Android 开发中,AndroidSchedulers.mainThread()
用于在主线程执行任务,像更新 UI 这类操作就需要在主线程完成。
以下是示例代码:
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
public class MainActivity extends AppCompatActivity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
// 创建一个 Observable
Observable<Integer> observable = Observable.range(1, 5);
// 使用 Schedulers.io() 进行数据发射,AndroidSchedulers.mainThread() 进行数据接收
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(value -> {
textView.setText("Received: " + value);
});
}
}
在这个 Android 示例里,subscribeOn(Schedulers.io())
让 Observable
的数据发射操作在 io()
调度器的线程池里执行,而 observeOn(AndroidSchedulers.mainThread())
则使 Observer
的数据接收操作在主线程执行,这样就能安全地更新 UI 了。
subscribeOn()
方法用于指定 Observable
发射数据的线程。无论该方法在链式调用里出现多少次,只有第一次调用会生效。
以下是示例代码:
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
// 创建一个 Observable
Observable<Integer> observable = Observable.range(1, 5);
// 多次调用 subscribeOn()
observable.subscribeOn(Schedulers.io())
.subscribeOn(Schedulers.computation())
.subscribe(value -> {
System.out.println("Received: " + value + " on thread: " + Thread.currentThread().getName());
});
在这个例子中,虽然多次调用了 subscribeOn()
,但只有第一次调用 subscribeOn(Schedulers.io())
会决定 Observable
发射数据的线程。
observeOn()
方法用于指定 Observer
接收数据的线程。该方法可以在链式调用中多次使用,每次调用都会改变后续操作所在的线程。
以下是示例代码:
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
// 创建一个 Observable
Observable<Integer> observable = Observable.range(1, 5);
// 多次调用 observeOn()
observable.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.map(value -> value * 2)
.observeOn(Schedulers.single())
.subscribe(value -> {
System.out.println("Received: " + value + " on thread: " + Thread.currentThread().getName());
});
在这个例子中,observeOn(Schedulers.computation())
让 map()
操作在 computation()
调度器的线程池里执行,而 observeOn(Schedulers.single())
则使 subscribe()
里的操作在 single()
调度器的单线程上执行。
Schedulers
类是一个工具类,提供了多个静态方法来获取不同类型的调度器。
public final class Schedulers {
// 单例模式,确保每个调度器只有一个实例
private static final Scheduler IO;
private static final Scheduler COMPUTATION;
private static final Scheduler SINGLE;
static {
// 初始化调度器实例
IO = RxJavaPlugins.initIoScheduler(new IOTask());
COMPUTATION = RxJavaPlugins.initComputationScheduler(new ComputationTask());
SINGLE = RxJavaPlugins.initSingleScheduler(new SingleTask());
}
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
public static Scheduler computation() {
return RxJavaPlugins.onComputationScheduler(COMPUTATION);
}
public static Scheduler single() {
return RxJavaPlugins.onSingleScheduler(SINGLE);
}
}
Schedulers
类采用单例模式,保证每个调度器只有一个实例。静态代码块负责初始化不同类型的调度器,而对应的静态方法则用于获取这些调度器实例。
subscribeOn()
和 observeOn()
方法是 Observable
类的实例方法。
public final Observable<T> subscribeOn(Scheduler scheduler) {
// 检查传入的调度器是否为 null
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
// 创建一个 ObservableSubscribeOn 对象,将当前 Observable 和调度器作为参数传入
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
public final Observable<T> observeOn(Scheduler scheduler) {
// 检查传入的调度器是否为 null
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
// 创建一个 ObservableObserveOn 对象,将当前 Observable 和调度器作为参数传入
return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler));
}
subscribeOn()
方法创建 ObservableSubscribeOn
实例,observeOn()
方法创建 ObservableObserveOn
实例,并且都会通过 RxJavaPlugins.onAssembly()
方法进行全局组装。
ObservableSubscribeOn
类和 ObservableObserveOn
类会在内部使用传入的调度器来安排任务的执行线程。例如,ObservableSubscribeOn
类会在 subscribeActual()
方法里使用调度器的 scheduleDirect()
方法来安排订阅操作在指定线程执行。
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
@Override
public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
static final class SubscribeOnObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {
private static final long serialVersionUID = 8094547886072529208L;
final Observer<? super T> actual;
SubscribeOnObserver(Observer<? super T> actual) {
this.actual = actual;
}
@Override
public void onSubscribe(Disposable s) {
DisposableHelper.setOnce(this, s);
}
@Override
public void onNext(T t) {
actual.onNext(t);
}
@Override
public void onError(Throwable t) {
actual.onError(t);
}
@Override
public void onComplete() {
actual.onComplete();
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
}
在 ObservableSubscribeOn
类中,subscribeActual()
方法创建 SubscribeOnObserver
实例,然后使用调度器的 scheduleDirect()
方法安排 SubscribeTask
任务在指定线程执行,SubscribeTask
任务会调用 source.subscribe(parent)
来完成订阅操作。
通过对调度器的分析可知,RxJava 的调度器机制为多线程编程提供了强大且灵活的支持,开发者能够依据不同的任务类型和需求选择合适的调度器,进而高效地管理线程资源。
在 RxJava 中,背压(Backpressure)是处理 Observable
发射数据速度和 Observer
处理数据速度不匹配问题的机制。当 Observable
发射数据的速度远快于 Observer
处理数据的速度时,会导致数据积压,可能引发内存溢出等问题。背压机制允许 Observer
告知 Observable
降低发射数据的速率,以此维持数据的稳定处理。
Buffer
策略会把 Observable
发射的数据存于缓冲区,直到 Observer
有能力处理这些数据。不过,若缓冲区无限制增大,可能会造成内存溢出。
以下是示例代码:
import io.reactivex.Flowable;
import io.reactivex.schedulers.Schedulers;
// 创建一个快速发射数据的 Flowable
Flowable<Integer> fastFlowable = Flowable.range(1, 1000)
.subscribeOn(Schedulers.computation());
// 使用 Buffer 策略
fastFlowable.onBackpressureBuffer()
.observeOn(Schedulers.single())
.subscribe(value -> {
try {
// 模拟缓慢处理数据
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Received: " + value);
});
在上述代码中,onBackpressureBuffer()
方法采用 Buffer
策略,把 Observable
发射的数据存于缓冲区,Observer
会逐个处理这些数据。
Drop
策略会在缓冲区满时丢弃新发射的数据,确保缓冲区不会无限增大。
以下是示例代码:
import io.reactivex.Flowable;
import io.reactivex.schedulers.Schedulers;
// 创建一个快速发射数据的 Flowable
Flowable<Integer> fastFlowable = Flowable.range(1, 1000)
.subscribeOn(Schedulers.computation());
// 使用 Drop 策略
fastFlowable.onBackpressureDrop()
.observeOn(Schedulers.single())
.subscribe(value -> {
try {
// 模拟缓慢处理数据
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Received: " + value);
});
在这个例子中,onBackpressureDrop()
方法采用 Drop
策略,当缓冲区满时,新发射的数据会被丢弃。
Latest
策略会在缓冲区满时丢弃旧数据,仅保留最新的数据,确保 Observer
处理的是最新的数据。
以下是示例代码:
import io.reactivex.Flowable;
import io.reactivex.schedulers.Schedulers;
// 创建一个快速发射数据的 Flowable
Flowable<Integer> fastFlowable = Flowable.range(1, 1000)
.subscribeOn(Schedulers.computation());
// 使用 Latest 策略
fastFlowable.onBackpressureLatest()
.observeOn(Schedulers.single())
.subscribe(value -> {
try {
// 模拟缓慢处理数据
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Received: " + value);
});
这里,onBackpressureLatest()
方法采用 Latest
策略,当缓冲区满时,旧数据会被丢弃,只保留最新的数据供 Observer
处理。
Error
策略会在缓冲区满时抛出 MissingBackpressureException
异常,提示背压问题。
以下是示例代码:
import io.reactivex.Flowable;
import io.reactivex.schedulers.Schedulers;
// 创建一个快速发射数据的 Flowable
Flowable<Integer> fastFlowable = Flowable.range(1, 1000)
.subscribeOn(Schedulers.computation());
// 使用 Error 策略
fastFlowable.onBackpressureError()
.observeOn(Schedulers.single())
.subscribe(value -> {
try {
// 模拟缓慢处理数据
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Received: " + value);
}, error -> {
System.out.println("Error: " + error.getMessage());
});
在这个示例中,onBackpressureError()
方法采用 Error
策略,当缓冲区满时会抛出异常,Observer
可以捕获该异常并进行相应处理。
Flowable
类是支持背压的 Observable
,它实现了 Publisher
接口,遵循 Reactive Streams 规范。
public abstract class Flowable<T> implements Publisher<T> {
// ... 其他代码 ...
public final Flowable<T> onBackpressureBuffer() {
return onBackpressureBuffer(Flowable.bufferSize(), false, false);
}
public final Flowable<T> onBackpressureBuffer(int capacity, boolean unbounded, boolean delayError) {
// 检查参数是否合法
ObjectHelper.verifyPositive(capacity, "capacity");
// 创建一个 FlowableOnBackpressureBuffer 对象,将当前 Flowable 和参数作为参数传入
return RxJavaPlugins.onAssembly(new FlowableOnBackpressureBuffer<T>(this, capacity, unbounded, delayError));
}
public final Flowable<T> onBackpressureDrop() {
// 创建一个 FlowableOnBackpressureDrop 对象,将当前 Flowable 作为参数传入
return RxJavaPlugins.onAssembly(new FlowableOnBackpressureDrop<T>(this));
}
public final Flowable<T> onBackpressureLatest() {
// 创建一个 FlowableOnBackpressureLatest 对象,将当前 Flowable 作为参数传入
return RxJavaPlugins.onAssembly(new FlowableOnBackpressureLatest<T>(this));
}
public final Flowable<T> onBackpressureError() {
// 创建一个 FlowableOnBackpressureError 对象,将当前 Flowable 作为参数传入
return RxJavaPlugins.onAssembly(new FlowableOnBackpressureError<T>(this));
}
// ... 其他代码 ...
}
Flowable
类提供了多个 onBackpressureXXX()
方法,用于设置不同的背压策略。这些方法会创建相应的 Flowable
子类实例,并通过 RxJavaPlugins.onAssembly()
方法进行全局组装。
FlowableOnBackpressureBuffer
类实现了 Buffer
策略,其核心代码如下:
public final class FlowableOnBackpressureBuffer<T> extends AbstractFlowableWithUpstream<T, T> {
final int capacity;
final boolean unbounded;
final boolean delayError;
public FlowableOnBackpressureBuffer(FlowableSource<T> source, int capacity, boolean unbounded, boolean delayError) {
super(source);
this.capacity = capacity;
this.unbounded = unbounded;
this.delayError = delayError;
}
@Override
protected void subscribeActual(Subscriber<? super T> s) {
// 创建一个 OnBackpressureBufferSubscriber 实例,用于处理背压
source.subscribe(new OnBackpressureBufferSubscriber<T>(s, capacity, unbounded, delayError));
}
static final class OnBackpressureBufferSubscriber<T> extends AtomicInteger implements FlowableSubscriber<T>, Subscription {
private static final long serialVersionUID = -2514538129242366402L;
final Subscriber<? super T> actual;
final int capacity;
final boolean unbounded;
final boolean delayError;
final SpscLinkedArrayQueue<T> queue;
Subscription s;
Throwable error;
boolean done;
boolean cancelled;
OnBackpressureBufferSubscriber(Subscriber<? super T> actual, int capacity, boolean unbounded, boolean delayError) {
this.actual = actual;
this.capacity = capacity;
this.unbounded = unbounded;
this.delayError = delayError;
this.queue = new SpscLinkedArrayQueue<T>(capacity);
}
@Override
public void onSubscribe(Subscription s) {
if (SubscriptionHelper.validate(this.s, s)) {
this.s = s;
actual.onSubscribe(this);
s.request(Long.MAX_VALUE);
}
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (!queue.offer(t)) {
s.cancel();
onError(new MissingBackpressureException("Buffer is full"));
return;
}
drain();
}
@Override
public void onError(Throwable t) {
if (done) {
RxJavaPlugins.onError(t);
return;
}
error = t;
done = true;
drain();
}
@Override
public void onComplete() {
if (done) {
return;
}
done = true;
drain();
}
@Override
public void request(long n) {
if (SubscriptionHelper.validate(n)) {
drain();
}
}
@Override
public void cancel() {
if (!cancelled) {
cancelled = true;
s.cancel();
if (getAndIncrement() == 0) {
queue.clear();
}
}
}
void drain() {
if (getAndIncrement() != 0) {
return;
}
int missed = 1;
final Subscriber<? super T> a = actual;
final SpscLinkedArrayQueue<T> q = queue;
for (;;) {
long r = requested.get();
long e = 0L;
while (e < r) {
if (cancelled) {
q.clear();
return;
}
boolean d = done;
T v = q.poll();
boolean empty = v == null;
if (d) {
if (delayError) {
if (empty) {
Throwable ex = error;
if (ex != null) {
a.onError(ex);
} else {
a.onComplete();
}
return;
}
} else {
Throwable ex = error;
if (ex != null) {
q.clear();
a.onError(ex);
return;
} else if (empty) {
a.onComplete();
return;
}
}
}
if (empty) {
break;
}
a.onNext(v);
e++;
}
if (e == r) {
if (cancelled) {
q.clear();
return;
}
boolean d = done;
boolean empty = q.isEmpty();
if (d) {
if (delayError) {
if (empty) {
Throwable ex = error;
if (ex != null) {
a.onError(ex);
} else {
a.onComplete();
}
return;
}
} else {
Throwable ex = error;
if (ex != null) {
q.clear();
a.onError(ex);
return;
} else if (empty) {
a.onComplete();
return;
}
}
}
}
if (e != 0) {
if (r != Long.MAX_VALUE) {
requested.addAndGet(-e);
}
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
}
}
在 FlowableOnBackpressureBuffer
类中,subscribeActual()
方法创建 OnBackpressureBufferSubscriber
实例来处理订阅逻辑。OnBackpressureBufferSubscriber
类的 onNext()
方法会把接收到的数据存入队列,若队列已满则取消订阅并抛出 MissingBackpressureException
异常。drain()
方法负责从队列中取出数据并发送给 Observer
,同时处理完成和错误信号。
通过对背压机制的分析,我们可以看到 RxJava 提供了多种背压策略,开发者能够根据具体需求选择合适的策略来处理 Observable
和 Observer
之间的数据速率不匹配问题,从而保证程序的稳定性和性能。
冷 Observable 的特点是,每当有新的订阅者订阅时,它都会重新开始发送数据。也就是说,每个订阅者都是从 Observable 序列的起始位置开始接收数据,它们之间相互独立,互不影响。冷 Observable 就像是一个“按需启动的任务”,只有在被订阅时才会执行数据发射操作。
import io.reactivex.Observable;
// 创建一个冷 Observable,每隔 1 秒发射一个整数
Observable<Long> coldObservable = Observable.interval(1, java.util.concurrent.TimeUnit.SECONDS);
// 第一个订阅者,在 2 秒后进行订阅
new java.util.concurrent.Thread(() -> {
try {
Thread.sleep(2000);
coldObservable.subscribe(value -> System.out.println("Subscriber 1: " + value));
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
// 第二个订阅者,在 3 秒后进行订阅
new java.util.concurrent.Thread(() -> {
try {
Thread.sleep(3000);
coldObservable.subscribe(value -> System.out.println("Subscriber 2: " + value));
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
在上述代码中,interval
操作符创建了一个冷 Observable,它会每隔 1 秒发射一个整数。第一个订阅者在 2 秒后订阅,从 2 开始接收数据;第二个订阅者在 3 秒后订阅,从 3 开始接收数据。每个订阅者都有独立的数据流,互不干扰。
以 Observable.interval
方法为例,其实现如下:
public static Observable<Long> interval(long period, TimeUnit unit) {
return interval(period, period, unit, Schedulers.computation());
}
public static Observable<Long> interval(long initialDelay, long period, TimeUnit unit, Scheduler scheduler) {
// 检查参数合法性
ObjectHelper.requireNonNull(unit, "unit is null");
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
if (period <= 0L) {
throw new IllegalArgumentException("period must be > 0: " + period);
}
if (initialDelay < 0L) {
throw new IllegalArgumentException("initialDelay must be >= 0: " + initialDelay);
}
// 创建一个 ObservableInterval 实例
return RxJavaPlugins.onAssembly(new ObservableInterval(initialDelay, period, unit, scheduler));
}
ObservableInterval
类继承自 Observable
,在其 subscribeActual
方法中,每当有新的订阅者订阅时,就会启动一个新的定时器任务,开始按照指定的时间间隔发射数据,从而实现了冷 Observable 的特性。
public final class ObservableInterval extends Observable<Long> {
// 存储初始延迟时间、周期、时间单位和调度器
final long initialDelay;
final long period;
final TimeUnit unit;
final Scheduler scheduler;
public ObservableInterval(long initialDelay, long period, TimeUnit unit, Scheduler scheduler) {
this.initialDelay = initialDelay;
this.period = period;
this.unit = unit;
this.scheduler = scheduler;
}
@Override
protected void subscribeActual(Observer<? super Long> observer) {
// 创建一个 IntervalObserver 实例,处理订阅逻辑
IntervalObserver is = new IntervalObserver(observer);
observer.onSubscribe(is);
// 基于调度器安排任务
scheduler.schedulePeriodicallyDirect(is, initialDelay, period, unit);
}
static final class IntervalObserver extends AtomicLong implements Disposable, Runnable {
private static final long serialVersionUID = 8545278565760005522L;
final Observer<? super Long> actual;
Disposable d;
IntervalObserver(Observer<? super Long> actual) {
this.actual = actual;
}
@Override
public void run() {
// 每次任务执行时,发射当前计数值
actual.onNext(getAndIncrement());
}
@Override
public void dispose() {
d.dispose();
}
@Override
public boolean isDisposed() {
return d.isDisposed();
}
@Override
public void onSubscribe(Disposable d) {
if (DisposableHelper.validate(this.d, d)) {
this.d = d;
}
}
}
}
热 Observable 与冷 Observable 相反,它在创建后就开始发射数据,无论是否有订阅者。并且,所有的订阅者都会接收从订阅时刻开始的后续数据,而不会重新启动数据发射流程。热 Observable 更像是一个持续运行的“广播源”,数据发射不受订阅者数量和订阅时间的影响。
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;
// 创建一个 PublishSubject,它是一个热 Observable
PublishSubject<Integer> hotObservable = PublishSubject.create();
// 第一个订阅者,在 2 秒后进行订阅
new java.util.concurrent.Thread(() -> {
try {
Thread.sleep(2000);
hotObservable.subscribe(value -> System.out.println("Subscriber 1: " + value));
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
// 发射一些数据
hotObservable.onNext(1);
hotObservable.onNext(2);
// 第二个订阅者,在 3 秒后进行订阅
new java.util.concurrent.Thread(() -> {
try {
Thread.sleep(3000);
hotObservable.subscribe(value -> System.out.println("Subscriber 2: " + value));
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
// 继续发射数据
hotObservable.onNext(3);
hotObservable.onNext(4);
在上述代码中,PublishSubject
创建了一个热 Observable。在没有任何订阅者时,就开始发射数据 1
和 2
。第一个订阅者在 2 秒后订阅,会接收到 3
和 4
;第二个订阅者在 3 秒后订阅,同样会接收到 3
和 4
,它们不会接收已经发射过的数据 1
和 2
。
以 PublishSubject
为例,它继承自 Subject
类,而 Subject
类同时实现了 Observable
和 Observer
接口,这使得它既可以发射数据(作为 Observable
),也可以接收数据(作为 Observer
)。
public final class PublishSubject<T> extends Subject<T> {
// 存储订阅者列表
private final AtomicReference<SubscriptionList> subscriptions;
public static <T> PublishSubject<T> create() {
return new PublishSubject<T>();
}
PublishSubject() {
subscriptions = new AtomicReference<SubscriptionList>();
}
@Override
public void onSubscribe(Subscription s) {
// 将订阅者添加到订阅者列表中
subscriptions.get().add(s);
}
@Override
public void onNext(T t) {
// 遍历订阅者列表,将数据发送给所有订阅者
SubscriptionList sl = subscriptions.get();
if (sl != null) {
sl.forEach(new Consumer<Subscriber<? super T>>() {
@Override
public void accept(Subscriber<? super T> s) {
s.onNext(t);
}
});
}
}
@Override
public void onError(Throwable t) {
// 遍历订阅者列表,将错误发送给所有订阅者
SubscriptionList sl = subscriptions.get();
if (sl != null) {
sl.dispose();
subscriptions.lazySet(null);
sl.forEach(new Consumer<Subscriber<? super T>>() {
@Override
public void accept(Subscriber<? super T> s) {
s.onError(t);
}
});
} else {
RxJavaPlugins.onError(t);
}
}
@Override
public void onComplete() {
// 遍历订阅者列表,将完成信号发送给所有订阅者
SubscriptionList sl = subscriptions.get();
if (sl != null) {
sl.dispose();
subscriptions.lazySet(null);
sl.forEach(new Consumer<Subscriber<? super T>>() {
@Override
public void accept(Subscriber<? super T> s) {
s.onComplete();
}
});
}
}
@Override
public void subscribeActual(Observer<? super T> s) {
// 创建一个 SubscriptionList 实例,并将订阅者添加进去
PublishDisposable<T> ps = new PublishDisposable<T>(s);
s.onSubscribe(ps);
SubscriptionList sl = subscriptions.get();
if (sl == null) {
sl = new SubscriptionList();
if (!subscriptions.compareAndSet(null, sl)) {
sl = subscriptions.get();
}
}
sl.add(ps);
}
}
PublishSubject
在创建后就可以通过 onNext
、onError
、onComplete
等方法发射数据和通知。当有新的订阅者订阅时,会将其添加到订阅者列表中,后续发射的数据会直接发送给所有已订阅的订阅者,体现了热 Observable 的特性。
可以使用 publish()
、share()
等操作符将冷 Observable 转换为热 Observable。
publish()
操作符会返回一个 ConnectableObservable
,需要调用 connect()
方法手动启动数据发射,此时所有订阅者会共享同一数据流。import io.reactivex.Observable;
import io.reactivex.observables.ConnectableObservable;
// 创建一个冷 Observable
Observable<Long> coldObservable = Observable.interval(1, java.util.concurrent.TimeUnit.SECONDS);
// 使用 publish() 转换为 ConnectableObservable
ConnectableObservable<Long> connectableObservable = coldObservable.publish();
// 第一个订阅者
connectableObservable.subscribe(value -> System.out.println("Subscriber 1: " + value));
// 第二个订阅者
connectableObservable.subscribe(value -> System.out.println("Subscriber 2: " + value));
// 手动启动数据发射
connectableObservable.connect();
share()
操作符是 publish().refCount()
的简便写法,它会自动管理连接,只要有至少一个订阅者就会启动数据发射,当没有订阅者时停止发射。import io.reactivex.Observable;
// 创建一个冷 Observable
Observable<Long> coldObservable = Observable.interval(1, java.util.concurrent.TimeUnit.SECONDS);
// 使用 share() 转换为热 Observable
Observable<Long> hotObservable = coldObservable.share();
// 第一个订阅者
hotObservable.subscribe(value -> System.out.println("Subscriber 1: " + value));
// 第二个订阅者
hotObservable.subscribe(value -> System.out.println("Subscriber 2: " + value));
可以使用 takeUntil()
、takeWhile()
等操作符,根据特定条件将热 Observable 转换为冷 Observable。例如,使用 takeUntil()
操作符在满足某个条件时停止热 Observable 的数据发射,从而使得后续订阅者重新开始接收数据,实现热转冷。
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;
import java.util.concurrent.TimeUnit;
// 创建一个热 Observable
PublishSubject<Integer> hotObservable = PublishSubject.create();
// 创建一个触发停止的 Observable
Observable<Long> stopSignal = Observable.timer(5, TimeUnit.SECONDS);
// 使用 takeUntil() 转换为冷 Observable
Observable<Integer> coldObservable = hotObservable.takeUntil(stopSignal);
// 第一个订阅者
coldObservable.subscribe(value -> System.out.println("Subscriber 1: " + value));
// 发射一些数据
hotObservable.onNext(1);
hotObservable.onNext(2);
// 第二个订阅者
coldObservable.subscribe(value -> System.out.println("Subscriber 2: " + value));
hotObservable.onNext(3);
hotObservable.onNext(4);
在上述代码中,hotObservable
是热 Observable,stopSignal
在 5 秒后触发。takeUntil(stopSignal)
使得 coldObservable
在 stopSignal
触发后停止接收 hotObservable
的数据,后续订阅者将重新开始接收数据,从而实现了热转冷的效果。
通过对热 Observable 和冷 Observable 的分析,开发者可以根据具体的业务场景选择合适的 Observable 类型,或者进行类型转换,以满足数据处理和多订阅者管理的需求。