1. 响应式编程范式
1.1 观察者模式 vs 迭代器模式
RxJava的核心是基于观察者模式的扩展,但融合了迭代器模式的思想:
- 观察者模式:数据生产者(Observable)和消费者(Observer)解耦
- 迭代器模式:以拉取(Pull)方式获取数据
- RxJava融合:采用推送(Push)方式,但保留迭代器的操作能力
// 传统观察者模式
interface Subject {
void registerObserver(Observer o);
void notifyObservers();
}
// RxJava的响应式扩展
Observable.create(emitter -> {
emitter.onNext("Data 1");
emitter.onNext("Data 2");
emitter.onComplete();
}).subscribe(data -> System.out.println(data));
1.2 数据流(Data Stream)思想
RxJava将事件视为在时间维度上流动的数据流:
- 流式处理:数据像水流一样流动,可被转换、过滤、组合
- 时间维度:事件在时间轴上分布,可处理延迟、间隔等
- 背压处理:当生产者速度 > 消费者速度时的流量控制策略
1.3 声明式编程优势
与命令式编程对比:
// 命令式编程(怎么做)
List<String> result = new ArrayList<>();
for (String name : names) {
if (name.startsWith("A")) {
result.add(name.toUpperCase());
}
}
// 声明式编程(做什么)
Observable.fromIterable(names)
.filter(name -> name.startsWith("A"))
.map(String::toUpperCase)
.subscribe(result::add);
优势:
- 代码简洁易读
- 易于组合和复用
- 关注点分离(业务逻辑与实现分离)
2. RxJava 核心三要素
2.1 Observable:数据源(被观察者)
Observable是RxJava的核心抽象,代表可观察的数据源:
-
特点:
- 可发送0到N个数据项
- 可发送完成或错误通知
- 支持背压(Backpressure)策略
-
创建方式:
// 1. 使用create()创建 Observable.create(emitter -> { emitter.onNext("Hello"); emitter.onNext("RxJava"); emitter.onComplete(); }); // 2. 使用just()创建 Observable.just("Single", "Value"); // 3. 从集合创建 Observable.fromIterable(Arrays.asList(1, 2, 3));
2.2 Observer:消费者(观察者)
Observer是数据流的终端消费者:
Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
// 订阅时调用
}
@Override
public void onNext(String s) {
// 接收数据项
}
@Override
public void onError(Throwable e) {
// 错误处理
}
@Override
public void onComplete() {
// 流完成
}
};
2.3 Operator:数据流转换
操作符是RxJava强大功能的基石:
-
分类:
- 创建操作符(create, just, from)
- 变换操作符(map, flatMap, groupBy)
- 过滤操作符(filter, take, skip)
- 组合操作符(merge, zip, combineLatest)
- 错误处理操作符(onErrorReturn, retry)
Observable.interval(1, TimeUnit.SECONDS)
.take(5) // 只取前5个
.map(i -> "Item " + i) // 转换格式
.filter(s -> !s.contains("3")) // 过滤数字3
.subscribe(System.out::println);
3. 事件类型与生命周期管理
3.1 事件类型
RxJava定义了三类核心事件:
| 事件类型 | 说明 | 特性 |
|---|---|---|
onNext(T value) | 发送数据项 | 可多次调用 |
onError(Throwable error) | 发送错误 | 终止事件流 |
onComplete() | 发送完成通知 | 终止事件流 |
重要规则:
- 一个Observable流只能以两种方式结束:
onComplete或onError onComplete和onError互斥,只能调用其中一个- 调用
onComplete或onError后不能再发送onNext
3.2 Disposable 机制
Disposable是RxJava管理订阅生命周期的核心机制:
Disposable disposable = Observable.interval(1, TimeUnit.SECONDS)
.subscribe(System.out::println);
// 需要取消订阅时
disposable.dispose();
源码解析:
// 关键接口
public interface Disposable {
void dispose(); // 取消订阅
boolean isDisposed(); // 是否已取消
}
实际应用:
// Android中防止内存泄漏
CompositeDisposable composite = new CompositeDisposable();
Disposable d1 = observable1.subscribe();
Disposable d2 = observable2.subscribe();
composite.addAll(d1, d2);
// 在onDestroy中取消所有订阅
composite.dispose();
4. RxJava 设计思想解析
4.1 链式调用设计
RxJava采用流畅接口(Fluent Interface)设计:
observable
.operator1()
.operator2()
.subscribe(observer);
实现原理:
- 每个操作符返回新的Observable
- 订阅时从下游向上游传递
4.2 响应式宣言
RxJava实现了响应式系统的核心原则:
- Responsive(响应性) :及时响应
- Resilient(韧性) :优雅的错误恢复
- Elastic(弹性) :背压支持
- Message Driven(消息驱动) :基于消息传递
4.3 热观察 vs 冷观察
| 类型 | 特点 | 示例 |
|---|---|---|
| 冷观察 | 每个订阅者收到完整数据流 | Observable.just() |
| 热观察 | 数据广播,新订阅者收不到之前数据 | Subject |
// 冷观察示例
Observable<String> cold = Observable.just("A", "B", "C");
cold.subscribe(s -> System.out.println("Sub1: " + s));
cold.subscribe(s -> System.out.println("Sub2: " + s));
// 输出:
// Sub1: A, Sub1: B, Sub1: C
// Sub2: A, Sub2: B, Sub2: C
// 热观察示例
Subject<String> hot = PublishSubject.create();
hot.subscribe(s -> System.out.println("Sub1: " + s));
hot.onNext("A");
hot.onNext("B");
hot.subscribe(s -> System.out.println("Sub2: " + s));
hot.onNext("C");
// 输出:
// Sub1: A, Sub1: B
// Sub1: C
// Sub2: C
本章总结
RxJava的核心思想是将异步事件和数据流转化为可观察的序列,通过操作符链式处理:
- 观察者模式:解耦生产者和消费者
- 数据流思想:事件在时间维度上流动
- 声明式编程:关注做什么而非如何做
- 三要素:Observable(源)、Observer(消费者)、Operator(转换)
- 生命周期:通过Disposable管理订阅
关键理解点:RxJava的核心价值在于提供了一套处理异步事件流的统一API,无论事件来自UI交互、网络请求还是本地数据,都可以用相同的模式处理。
在下一章中,我们将深入RxJava的源码实现,解析Observable的创建过程和线程调度机制。