RxJava 是一个基于观察者模式的异步编程库,它扩展了观察者模式以支持数据/事件序列,并添加了操作符支持。对于刚接触响应式编程的开发者来说,理解几个核心概念至关重要:
Observable(被观察者):数据源或事件源,负责发射数据项或通知。在RxJava中,Observable可以发射零个或多个数据项,然后可能以完成或错误终止。例如,一个网络请求的响应可以建模为一个Observable。
Observer(观察者):订阅Observable并对其发射的数据项或通知做出响应。Observer接口定义了四个方法:
Subscription(订阅):表示Observer与Observable之间的连接。通过Subscription,Observer可以取消对Observable的订阅,从而停止接收通知。
Scheduler(调度器):控制Observable操作在哪个线程上执行。RxJava提供了几种内置的Scheduler:
RxJava提供了多种创建Observable的方式:
java复制// 1. 使用just()创建发射固定数据的Observable
Observable<String> observable1 = Observable.just("Hello", "World");
// 2. 使用fromIterable()从集合创建Observable
List<String> list = Arrays.asList("Apple", "Banana", "Orange");
Observable<String> observable2 = Observable.fromIterable(list);
// 3. 使用create()手动创建Observable
Observable<String> observable3 = Observable.create(emitter -> {
emitter.onNext("Data 1");
emitter.onNext("Data 2");
emitter.onComplete();
});
// 4. 使用interval()创建定时发射数据的Observable
Observable<Long> observable4 = Observable.interval(1, TimeUnit.SECONDS);
Observer是观察者,负责处理Observable发射的数据:
java复制Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
// 当订阅建立时调用
Log.d("RxJava", "onSubscribe");
}
@Override
public void onNext(String s) {
// 接收到新数据时调用
Log.d("RxJava", "onNext: " + s);
}
@Override
public void onError(Throwable e) {
// 发生错误时调用
Log.e("RxJava", "onError", e);
}
@Override
public void onComplete() {
// 数据发射完成时调用
Log.d("RxJava", "onComplete");
}
};
创建Observable和Observer后,需要建立订阅关系:
java复制Observable<String> observable = Observable.just("Hello", "World");
observable.subscribe(observer);
也可以使用更简洁的lambda表达式方式:
java复制Observable.just("Hello", "World")
.subscribe(
item -> Log.d("RxJava", "onNext: " + item),
error -> Log.e("RxJava", "onError", error),
() -> Log.d("RxJava", "onComplete")
);
map():对Observable发射的每个数据项应用一个函数进行转换
java复制Observable.just(1, 2, 3)
.map(number -> "Number: " + number)
.subscribe(System.out::println);
flatMap():将每个数据项转换为一个新的Observable,然后将这些Observable发射的数据合并
java复制Observable.just("Apple", "Banana")
.flatMap(fruit -> Observable.fromArray(fruit.split("")))
.subscribe(System.out::println);
filter():只发射满足特定条件的数据项
java复制Observable.range(1, 10)
.filter(number -> number % 2 == 0)
.subscribe(System.out::println);
take():只发射前N项数据
java复制Observable.interval(1, TimeUnit.SECONDS)
.take(5)
.subscribe(System.out::println);
zip():将多个Observable发射的数据项按顺序组合
java复制Observable<String> letters = Observable.just("A", "B", "C");
Observable<Integer> numbers = Observable.just(1, 2, 3);
Observable.zip(letters, numbers,
(letter, number) -> letter + number)
.subscribe(System.out::println);
merge():将多个Observable的发射合并为一个
java复制Observable<String> first = Observable.just("A", "B");
Observable<String> second = Observable.just("C", "D");
Observable.merge(first, second)
.subscribe(System.out::println);
RxJava默认是同步的,但可以通过调度器控制操作在哪个线程执行:
java复制Observable.just("Hello")
.subscribeOn(Schedulers.io()) // 指定Observable在IO线程执行
.observeOn(AndroidSchedulers.mainThread()) // 指定Observer在主线程接收
.subscribe(System.out::println);
java复制Observable.fromCallable(() -> {
// 在IO线程执行耗时操作
return fetchDataFromNetwork();
})
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.map(data -> {
// 在计算线程处理数据
return processData(data);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
// 在主线程更新UI
updateUI(result);
});
java复制// 使用Retrofit配合RxJava
@GET("users/{user}/repos")
Observable<List<Repo>> listRepos(@Path("user") String user);
// 调用网络请求
apiService.listRepos("octocat")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(repos -> {
// 更新UI
adapter.setData(repos);
}, error -> {
// 处理错误
showError(error);
});
java复制Observable.fromCallable(() -> {
// 执行耗时操作
return heavyComputation();
})
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
// 更新UI
textView.setText(result);
});
java复制RxView.clicks(button)
.throttleFirst(500, TimeUnit.MILLISECONDS) // 防止快速连续点击
.subscribe(unit -> {
// 处理点击事件
performAction();
});
在Android中使用RxJava时,需要注意Activity/Fragment生命周期导致的内存泄漏:
java复制// 使用CompositeDisposable管理订阅
private CompositeDisposable disposables = new CompositeDisposable();
disposables.add(Observable.interval(1, TimeUnit.SECONDS)
.subscribe(System.out::println));
// 在onDestroy中清理
@Override
protected void onDestroy() {
super.onDestroy();
disposables.clear();
}
RxJava提供了多种错误处理方式:
java复制// 1. 使用onError回调
observable.subscribe(
item -> {},
error -> { /* 处理错误 */ }
);
// 2. 使用onErrorReturn
observable.onErrorReturn(error -> "Default Value")
.subscribe(System.out::println);
// 3. 使用onErrorResumeNext
observable.onErrorResumeNext(Observable.just("Fallback"))
.subscribe(System.out::println);
当生产者发射数据速度超过消费者处理速度时,会导致背压问题:
java复制// 使用Flowable处理背压
Flowable.range(1, 1000000)
.onBackpressureBuffer() // 缓冲策略
.observeOn(Schedulers.computation())
.subscribe(System.out::println);
java复制TestScheduler testScheduler = new TestScheduler();
TestObserver<String> testObserver = new TestObserver<>();
Observable.interval(1, TimeUnit.SECONDS, testScheduler)
.map(i -> "Item " + i)
.take(5)
.subscribe(testObserver);
// 快进时间
testScheduler.advanceTimeBy(5, TimeUnit.SECONDS);
// 验证结果
testObserver.assertComplete();
testObserver.assertValueCount(5);
testObserver.assertValues("Item 0", "Item 1", "Item 2", "Item 3", "Item 4");