rxjava Emitter

        在Android开发中,RxJava是一个流行的库,用于处理异步和基于事件的编程。RxJava 中的 Emitter 是一个接口(组件),用于发射 Observable 的事件(onNext、onComplete、onError)。它是创建 Observable 时的核心组件,允许你手动控制数据流。根据不同场景,RxJava 提供了三种 Emitter:

  1. SyncEmitter:同步发射事件,必须遵循 RxJava 的规则(如在 onComplete/onError 后不再发射事件)。
  2. AsyncEmitter:异步发射事件,支持背压(Backpressure)。
  3. 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);
    }
}

关键注意事项

  1. 遵守发射规则

    • 必须在 onComplete 或 onError 后停止发射数据。
    • 不能同时调用 onComplete 和 onError
    • 一旦调用 onComplete 或 onError,Observable 的生命周期结束。
  2. 处理背压
    如果异步发射数据且下游处理速度慢,需使用支持背压的操作符(如 Flowable)或适当的策略(如 buffersample)。

  3. 资源管理
    在 onSubscribe 中返回的 Disposable 可用于取消订阅,防止内存泄漏。例如:

    emitter.setCancellable(() -> {
        // 释放资源的代码
    });
    
  4. 线程安全
    如果在多线程环境中使用 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 的关键。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值