在现代 Android 开发中,RxJava 已成为处理异步编程、事件流控制和数据变换的核心工具之一。无论是 API 请求、数据库查询,还是复杂的 UI 交互,RxJava 都能提供流式、声明式的编程范式,使代码更加清晰、可维护。
RxJava 的应用场景非常广泛,常见的使用方式包括:
- 异步操作:如网络请求、数据库查询,避免阻塞主线程,提高应用响应速度。
- 数据流处理:流式操作数据,如列表变换、过滤、合并等,提高代码的可读性。
- 事件驱动编程:监听用户交互事件、消息总线等,实现响应式编程。
- 多线程管理:通过
Schedulers轻松切换线程,提高任务执行效率。 - 错误处理:提供灵活的异常捕获和重试机制,增强系统健壮性。
作为响应式编程的代表,RxJava 在 Android 领域的使用率非常高。特别是在 MVVM 架构、数据流处理、异步任务 等场景中,RxJava 已成为 Jetpack 组件(如 LiveData、Room、Paging)的重要补充。虽然 Kotlin Coroutine 近年来逐渐普及,但 RxJava 仍然在许多大型项目和第三方库(如 Retrofit、Room)中扮演重要角色。
接下来,我们将深入解析 RxJava 的核心原理,包括 Observable 的工作机制、操作符的执行流程,以及底层的线程切换原理。
1.设计思想
- 观察者模式(Observable-Pattern / Publish-Subscribe-Pattern)
- 链式调用
指的是在一个表达式中连续调用多个方法,每个方法的返回值通常是同一个对象(this),从而可以继续调用下一个方法。它常用于流式API设计,提升代码的可读性和可维护性。在构建者模式中常见。
2.类图概览
3.简单使用
// ObservableCreate
Observable.create<Int> { // ObservableEmitter
it.onNext(1)
it.onNext(2)
it.onNext(3)
} .subscribeOn(Schedulers.io()) // ObservableSubscribeOn
.observeOn(Schedulers.io()) // Observale
.subscribe {
println(it)
}
调用链时序图
-
Observable:通过函数调用,一层层封装Observable,然后逐层调用逻辑,在这个过程中添加对线程切换的操作,**
source**成员变量保存的是封装前的Observable对象 -
Observer: 在执行的过程中也会根据对应Observable的情况对Observer(常见的是root parent是LambdaObserver对象)进行封装,例如:
.map对应的 Observable是ObservableMap, 会在observeActual中将Observer封装为MapObserver
4.分析
从上面的调用时序图,我们就通过下面两个类中的源码来进一步理解一下,Rxjava的调度过程。
Observable.create
public interface ObservableOnSubscribe<T> {
/**
* Called for each Observer that subscribes.
* @param e the safe emitter instance, never null
* @throws Exception on error
*/
void subscribe(ObservableEmitter<T> e) throws Exception;
}
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Observable<T> create(@NonNull ObservableOnSubscribe<T> source) {
Objects.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<>(source));
}
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<>(observer); // 最终会在xxxEmitter中调用Observer对应的方法
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
if (t == null) {
onError(ExceptionHelper.createNullPointerException("onNext called with a null value."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
...
}
}
RxJavaPlugins 是 RxJava 库中的一个重要工具类,它提供了一种全局拦截和修改 RxJava 操作符行为的机制。允许你在 RxJava 的操作符执行前后插入自定义逻辑。例如,你可以使用 setOnObservableAssembly 方法拦截所有 Observable 的创建过程,在 Observable 被创建时执行额外的逻辑。
在得到了 Observable 对象后,接着链式调用对应的方法。
Observable.subscribeOn
当我们调用这个方法时,我们会得到封装的Observable,ObservableSubscribeOn
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
@Override
public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
s.onSubscribe(parent);
// 在这切换线程,扔到调度器中调度
parent.setDisposable(scheduler.scheduleDirect(new Runnable() {
@Override
public void run() {
// 执行封装前 原始 Observable 的subscribe的方法
source.subscribe(parent);
}
}));
}
static final class SubscribeOnObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {
private static final long serialVersionUID = 8094547886072529208L;
final Observer<? super T> actual;
final AtomicReference<Disposable> s;
SubscribeOnObserver(Observer<? super T> actual) {
this.actual = actual;
this.s = new AtomicReference<Disposable>();
}
@Override
public void onSubscribe(Disposable s) {
DisposableHelper.setOnce(this.s, s);
}
@Override
public void onNext(T t) {
// 调用封装前原始的 Observer 中的方法
actual.onNext(t);
}
...
}
到这,我们就能大致理解了Rxjava的原理,通过封装,逐层处理,来达到实现不同的功能——切线程、处理输入输出等等。