在Android开发中,RxJava是一个流行的库,用于处理异步和基于事件的编程。RxJava 中的 Emitter
是一个接口(组件),用于发射 Observable 的事件(onNext、onComplete、onError)。它是创建 Observable 时的核心组件,允许你手动控制数据流。根据不同场景,RxJava 提供了三种 Emitter:
- SyncEmitter:同步发射事件,必须遵循 RxJava 的规则(如在 onComplete/onError 后不再发射事件)。
- AsyncEmitter:异步发射事件,支持背压(Backpressure)。
- SerializedEmitter:线程安全的发射器,自动处理多线程并发问题。
Emitter有几个方法,可以发射不同类型的事件:
-
onNext(Object)
: 发射一个非结束事件。 -
onCompleted()
: 发射一个完成事件,表示事件流结束。 -
onError(Throwable)
: 发射一个错误事件,表示事件流出现异常。
基本用法示例
下面是一个使用 Observable.create()
和 Emitter
创建自定义 Observable 的示例:
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.subjects.PublishSubject;
public class EmitterExample {
public static void main(String[] args) {
// 创建一个 Observable,使用 Emitter 发射数据
Observable<Integer> source = Observable.create(emitter -> {
try {
// 发射数据项
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
// 检查订阅状态,避免在取消订阅后继续发射
if (!emitter.isDisposed()) {
emitter.onComplete();
}
} catch (Exception e) {
// 发生错误时发射错误
emitter.onError(e);
}
});
// 创建一个 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.err.println("onError: " + e.getMessage());
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
};
// 订阅 Observable
source.subscribe(observer);
}
}
关键注意事项
-
遵守发射规则:
- 必须在
onComplete
或onError
后停止发射数据。 - 不能同时调用
onComplete
和onError
。 - 一旦调用
onComplete
或onError
,Observable 的生命周期结束。
- 必须在
-
处理背压:
如果异步发射数据且下游处理速度慢,需使用支持背压的操作符(如Flowable
)或适当的策略(如buffer
、sample
)。 -
资源管理:
在onSubscribe
中返回的Disposable
可用于取消订阅,防止内存泄漏。例如:emitter.setCancellable(() -> { // 释放资源的代码 });
-
线程安全:
如果在多线程环境中使用Emitter
,建议使用Observable.create()
配合serialize()
操作符确保线程安全。
Emitter 是 RxJava 中强大的工具,但需谨慎使用以避免违反 RxJava 的规则导致难以调试的问题。
RxJava 的核心概念远不止 Emitter
,它基于响应式编程范式,通过异步数据流将生产者和消费者解耦。以下是 RxJava 中其他关键的核心概念:
1. Observable / Flowable
角色:数据的生产者,负责发出事件序列。
区别:
- Observable:不支持背压(Backpressure),适用于事件数量较少或处理速度快的场景。
- Flowable:支持背压,通过
Subscriber
控制数据流速,防止数据过载。
示例:
// 创建 Observable(不支持背压)
Observable.just("A", "B", "C")
.subscribe(System.out::println);
// 创建 Flowable(支持背压)
Flowable.range(1, 1000)
.subscribe(
System.out::println, // onNext
Throwable::printStackTrace, // onError
() -> System.out.println("Completed") // onComplete
);
2. Observer / Subscriber
角色:数据的消费者,监听 Observable/Flowable 发出的事件。
核心方法:
onNext(T value)
:接收数据项。onError(Throwable e)
:处理错误并终止流。onComplete()
:流正常结束时调用。
示例:
Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("订阅成功");
}
@Override
public void onNext(String value) {
System.out.println("接收到: " + value);
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onComplete() {
System.out.println("流已完成");
}
};
Observable.just("Hello", "World").subscribe(observer);
3. Disposable
作用:管理订阅关系,允许在需要时取消订阅,防止内存泄漏。
方法:
dispose()
:取消订阅。isDisposed()
:检查是否已取消。
示例:
Disposable disposable = Observable.interval(1, TimeUnit.SECONDS)
.subscribe(System.out::println);
// 5秒后取消订阅
Thread.sleep(5000);
disposable.dispose();
4. Scheduler
作用:控制数据流的执行线程(如 IO、计算、UI 线程)。
常用 Scheduler:
Schedulers.io()
:适用于 IO 密集型操作(如网络请求)。Schedulers.computation()
:适用于计算密集型操作。AndroidSchedulers.mainThread()
(Android 平台):用于 UI 更新。
示例:
Observable.just("A", "B", "C")
.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
.observeOn(AndroidSchedulers.mainThread()) // 指定回调在主线程
.subscribe(System.out::println);
5. 操作符(Operators)
作用:转换、过滤、组合数据流,实现复杂的数据处理逻辑。
分类:
- 创建操作符:
just()
、from()
、interval()
、create()
。 - 转换操作符:
map()
、flatMap()
、buffer()
、scan()
。 - 过滤操作符:
filter()
、take()
、distinct()
、debounce()
。 - 组合操作符:
merge()
、concat()
、zip()
、combineLatest()
。 - 错误处理:
onErrorReturn()
、retry()
、catchError()
。
示例:
Observable.just(1, 2, 3, 4)
.map(num -> num * 10) // 转换:每个元素乘以10
.filter(num -> num > 20) // 过滤:只保留大于20的元素
.subscribe(System.out::println); // 输出:30, 40
6. Subject
特性:既是 Observable 又是 Observer,可同时发射和接收事件。
常见类型:
- PublishSubject:只发射订阅后产生的事件。
- BehaviorSubject:发射订阅前的最后一个事件 + 订阅后的所有事件。
- ReplaySubject:缓存所有事件,订阅者会收到全部历史数据。
- AsyncSubject:只发射最后一个事件(在
onComplete()
之后)。
示例:
PublishSubject<String> subject = PublishSubject.create();
subject.onNext("Event 1"); // 订阅前的事件不会被收到
subject.subscribe(System.out::println); // 订阅者开始监听
subject.onNext("Event 2"); // 输出:Event 2
subject.onNext("Event 3"); // 输出:Event 3
7. 背压(Backpressure)
问题:当 Observable 发射速度 > Observer 处理速度时,可能导致内存溢出。
解决方案:
- 使用
Flowable
替代 Observable。 - 应用背压策略:
BUFFER
:缓存所有事件(可能 OOM)。DROP
:丢弃无法处理的事件。LATEST
:只保留最新的事件。
示例:
Flowable.range(1, 1000)
.onBackpressureDrop() // 丢弃无法处理的事件
.observeOn(Schedulers.io())
.subscribe(System.out::println);
总结
RxJava 通过这些核心概念构建了强大的异步数据流处理能力,让代码更简洁、可维护,并有效管理并发和资源。掌握这些概念是使用 RxJava 的关键。