一、基本概念
RxJava 中的一些基本概念包括:
-
Observable(被观察者)
Observable 是一个数据流的源头,它可以发出三种类型的事件:发射数据(OnNext),发射一个错误(OnError),或者发射完成(OnComplete)。 -
Observer(观察者)
Observer 是消费 Observable 产生的数据流的实体。它有三个方法对应 Observable 的三种事件类型:onNext,onError 和 onComplete。
Subscription(订阅):当 Observer 订阅 Observable 时,就会创建一个 Subscription。这个 Subscription 可以用来取消订阅,防止内存泄露。 -
Operators(操作符)
RxJava 提供了许多操作符,比如 map,filter,reduce 等等,这些操作符可以用来操作和转换数据流。
Schedulers(调度器):RxJava 的 Schedulers 可以用来控制 Observable 的运行在哪个线程,或者将 Observer 的执行切换到指定的线程。 -
Subject(主题)
Subject 同时实现了 Observable 和 Observer 的接口,因此它既可以作为被观察者,也可以作为观察者。RxJava 提供了几种不同的 Subject,比如 BehaviorSubject,ReplaySubject, PublishSubject 和 AsyncSubject。 -
Backpressure(背压)
-当 Observable 发出数据的速度快于 Observer 处理的速度,就可能会出现 Backpressure 的问题。RxJava 提供了一些策略来处理这种情况。
以上就是 RxJava 的一些基本概念,理解这些概念是学习和使用 RxJava 的基础。
二、Rxjava中的四种 Subject
- PublishSubject: 只会把在订阅发生的时间点之后来自原始 Observable 的数据发射给观察者。
PublishSubject<Integer> subject = PublishSubject.create();
subject.onNext(1);
subject.subscribe(System.out::println);
subject.onNext(2); // 输出 2
- BehaviorSubject: 会发送订阅之前的最后一个值(如果有的话)和订阅之后的所有值。(它会向观察者发送订阅之前的最后一个值,或者如果没有任何值被发送,它会发送一个默认值)
BehaviorSubject<String> subject = BehaviorSubject.createDefault("Default Value");
subject.subscribe(value -> System.out.println("Observer 1: " + value));
subject.onNext("Value 1");
subject.onNext("Value 2");
subject.subscribe(value -> System.out.println("Observer 2: " + value));
subject.onNext("Value 3");
subject.onNext("Value 4");
subject.onComplete();
在这个示例中,BehaviorSubject 会首先发送默认值给第一个观察者。然后,当新的值被发出时,第一个观察者会接收到这些新值。当第二个观察者订阅时,它会首先接收到最后一次发出的值,即 “Value 2”,然后继续接收后续发出的值。
输出结果如下:
Observer 1: Default Value
Observer 1: Value 1
Observer 1: Value 2
Observer 2: Value 2
Observer 1: Value 3
Observer 2: Value 3
Observer 1: Value 4
Observer 2: Value 4
请注意,尽管第二个观察者在 “Value 2” 被发出后才订阅,但是它依然可以接收到 “Value 2”。这是因为 BehaviorSubject 会发送最后一次发出的值给新的观察者。
- ReplaySubject:
ReplaySubject 是 RxJava 中的一种 Subject 类型,它和其他的 Subject 最大的区别是,它会缓存所有发射给它的数据。当一个新的观察者订阅时,ReplaySubject 会将这些缓存的数据都发射给这个新的观察者。
ReplaySubject<Integer> subject = ReplaySubject.create();
subject.onNext(1);
subject.onNext(2);
subject.onNext(3);
subject.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
System.out.println("Observer 1: " + value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
subject.onNext(4);
subject.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
System.out.println("Observer 2: " + value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
subject.onNext(5);
// 输出:
// Observer 1: 1
// Observer 1: 2
// Observer 1: 3
// Observer 1: 4
// Observer 2: 1
// Observer 2: 2
// Observer 2: 3
// Observer 2: 4
// Observer 1: 5
// Observer 2: 5
在这个例子中,当第二个观察者订阅时,它会接收到所有之前 ReplaySubject 接收到的数据(1,2,3,4)。然后,当 ReplaySubject 发射一个新的数据(5)时,两个观察者都会接收到这个新的数据。
- AsyncSubject:
AsyncSubject 是 RxJava 中的一种 Subject 类型。和其他类型的 Subject 不同,AsyncSubject 只有在源 Observable 执行完毕后,才会把最后一个值发射出去。
AsyncSubject<Integer> subject = AsyncSubject.create();
subject.onNext(1);
subject.onNext(2);
subject.onNext(3);
subject.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
System.out.println("Observer 1: " + value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
System.out.println("Observer 1: Complete");
}
});
subject.onNext(4);
subject.onComplete();
subject.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
System.out.println("Observer 2: " + value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
System.out.println("Observer 2: Complete");
}
});
// 输出:
// Observer 1: 4
// Observer 1: Complete
// Observer 2: 4
// Observer 2: Complete
在这个例子中,只有在调用 onComplete 方法后,AsyncSubject 才会把最后一个值(4)发射给观察者。并且,即使第二个观察者在 onComplete 调用后才订阅,它也会收到最后一个值。
三、Rxjava中操作符
RxJava 提供了大量的操作符,以支持各种各样的数据操作。以下是一些常用的 RxJava 操作符:
1、创建操作符:如 create(), just(), from(), range(), interval(), timer() 等,用于创建 Observable。
2、转换操作符:如 map(), flatMap(), concatMap(), switchMap(), buffer(), groupBy() 等,用于转换 Observable 发出的数据。
3、过滤操作符:如 filter(), take(), skip(), first(), last(), debounce(), distinct(), elementAt() 等,用于过滤 Observable 发出的数据。
4、组合操作符:如 zip(), merge(), concat(), combineLatest(), startWith(), join() 等,用于将多个 Observable 组合成一个 Observable。
5、错误处理操作符:如 onErrorReturn(), onErrorResumeNext(), retry(), retryWhen() 等,用于处理 Observable 发出的错误。
6、工具操作符:如 delay(), doOnEach(), doOnNext(), doOnError(), subscribeOn(), observeOn() 等,用于对 Observable 进行一些辅助操作。
7、条件和布尔操作符:如 all(), contains(), isEmpty(), amb(), defaultIfEmpty() 等,用于对 Observable 发出的数据进行条件判断。
8、数学和集合操作符:如 count(), reduce(), collect(), toList(), toSortedList() 等,用于对 Observable 发出的数据进行数学运算或集合操作。
四、Rxjava中的Subscription
在 RxJava 中,Subscription 是 Observable 和 Observer 之间的连接,当 Observer 订阅 Observable 时,会返回一个 Subscription 对象。这个对象有一些方法可以控制订阅的生命周期。
以下是 RxJava 中 Subscription 的一些主要方法:
unsubscribe():这个方法用于取消订阅,当你不再需要接收数据时,可以调用这个方法取消订阅,防止内存泄漏。
isUnsubscribed():这个方法用于检查是否已经取消订阅。
在 RxJava 2.x 中,Subscription 被替换为了 Disposable,它提供了类似的方法,如 dispose() 和 isDisposed()。
请注意,在使用 Subscription 或 Disposable 时,要确保在适当的时候取消订阅(或者调用 dispose() 方法),例如在 Android 中的 Activity 或 Fragment 的 onDestroy() 方法中,以防止内存泄漏。
Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS);
Subscription subscription = observable.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
System.out.println(aLong);
}
});
// 等待5秒
Thread.sleep(5000);
// 取消订阅
subscription.unsubscribe();
在这个示例中,我们创建了一个每秒发射一个数字的 Observable。然后,我们订阅这个 Observable,并获取到一个 Subscription 对象。然后,我们等待5秒,然后调用 unsubscribe() 方法取消订阅。这样,我们就不会再接收到 Observable 发出的数据。
需要注意的是,如果你在 Android 中使用 RxJava,你可能需要在 Activity 或 Fragment 的 onDestroy() 方法中取消订阅,以防止内存泄漏。
另外,请注意,在 RxJava 2.x 和 3.x 中,Subscription 被替换为了 Disposable,但是使用方式类似。
Disposable举例:
Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS);
Disposable disposable = observable.subscribe(aLong -> System.out.println(aLong));
// 等待5秒
Thread.sleep(5000);
// 取消订阅
disposable.dispose();