两张图读懂RxJava源码

149 阅读4分钟

源码仓库:github.com/ReactiveX/R…

在现代 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)

image.png

  • 链式调用

指的是在一个表达式中连续调用多个方法,每个方法的返回值通常是同一个对象(this),从而可以继续调用下一个方法。它常用于流式API设计,提升代码的可读性和可维护性。在构建者模式中常见。

2.类图概览

image.png

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)
    } 

调用链时序图

image.png

  • 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的原理,通过封装,逐层处理,来达到实现不同的功能——切线程、处理输入输出等等。