RxJava工作原理介绍

235 阅读4分钟

工作原理概述

RxJava 的工作原理主要围绕响应式编程的概念,通过 Observable(被观察者)发射数据,Observer(观察者)接收数据,并通过 Scheduler 实现多线程处理。核心思想是将数据流作为一个异步序列来处理,允许灵活的组合和操作数据流。

内部成员

  • Observable:被观察者,用于发射数据流。
  • Observer:观察者,用于接收和处理数据流。
  • Subscribe:将 Observer 订阅到 Observable,建立订阅关系。
  • Disposable:用于管理订阅,可以通过 dispose() 方法取消订阅。
  • Scheduler:用于指定 ObservableObserver 在不同线程中执行,实现线程切换。

被观察者 Observable 的创建过程

Observable 的创建过程涉及多个静态方法和创建函数。以 Observable.create() 为例。

示例代码

val observable: Observable<String> = Observable.create(object : ObservableOnSubscribe<String> {
    override fun subscribe(emitter: ObservableEmitter<String>) {
        emitter.onNext("Hello RxJava")
        emitter.onComplete()
    }
})

create 方法:

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    ObjectHelper.requireNonNull(source, "source is null");
    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
  • Observable.create() 方法接收一个 ObservableOnSubscribe 实例,该实例定义了数据的发射逻辑。
  • ObjectHelper.requireNonNull() 用于检查 source 是否为 null,避免空指针异常。
  • RxJavaPlugins.onAssembly() 是一个钩子,用于在创建 Observable 时执行一些全局配置。
  • 最终返回一个 ObservableCreate(观察者) 实例。

ObservableCreate 对象:

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);
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }
}
  • ObservableCreateObservable 的一个子类,持有 ObservableOnSubscribe 对象。
  • subscribeActual 方法是实际的订阅实现。它会执行 source.subscribe(parent) 方法,即 ObservableOnSubscribesubscribe 方法。

观察者 Observer 的创建过程

Observer 是一个接口,定义了四个方法:onSubscribe()onNext()onError()onComplete()。一个典型的 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() {
        // 完成时回调
    }
};

订阅过程

订阅过程是通过调用 Observable.subscribe() 方法完成的。以下是 Observable.subscribe() 方法的实现:

public final void subscribe(Observer<? super T> observer) {
    Objects.requireNonNull(observer, "observer is null");
    try {
        observer = RxJavaPlugins.onSubscribe(this, observer);
        Objects.requireNonNull(observer, "Plugin returned null Observer");
        subscribeActual(observer);
    } catch (NullPointerException | IllegalArgumentException | IllegalStateException ex) {
        RxJavaPlugins.onError(ex);
        throw ex;
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        RxJavaPlugins.onError(ex);
        new NullPointerException("Actually not, but can't throw other exceptions due to RS").initCause(ex);
        throw ex;
    }
}
  • RxJavaPlugins.onSubscribe() 用于在订阅时执行一些全局配置。
  • subscribeActual(observer) 是实际订阅的核心方法,由 ObservableCreate 实现。

以下是 ObservableCreate 中的 subscribeActual() 方法:

@Override
protected void subscribeActual(Observer<? super T> observer) {
    CreateEmitter<T> parent = new CreateEmitter<>(observer);
    observer.onSubscribe(parent);
    try {
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}
  • 创建 CreateEmitter,这是 ObservableEmitter 的一个实现,用于将事件发射给 Observer
  • 调用 Observer.onSubscribe() 传递 Disposable
  • 调用 ObservableOnSubscribe.subscribe() 方法,开始发射事件。

CreateEmitter

CreateEmitterObservableEmitter 的一个实现,用于将事件发射给 Observer。它实现了 Disposable 接口,可以管理订阅的生命周期。以下是 CreateEmitter 的简化代码:

public final class CreateEmitter<T> extends AtomicReference<Disposable> implements ObservableEmitter<T>, Disposable {
    final Observer<? super T> observer;

    public CreateEmitter(Observer<? super T> observer) {
        this.observer = observer;
    }

    @Override
    public void onNext(T value) {
        if (!isDisposed()) {
            observer.onNext(value);
        }
    }

    @Override
    public void onError(Throwable e) {
        if (!isDisposed()) {
            observer.onError(e);
        }
    }

    @Override
    public void onComplete() {
        if (!isDisposed()) {
            observer.onComplete();
        }
    }

    @Override
    public void dispose() {
        DisposableHelper.dispose(this);
    }

    @Override
    public boolean isDisposed() {
        return get() == DisposableHelper.DISPOSED;
    }
}
  • CreateEmitter 持有 Observer,并通过 AtomicReference 实现线程安全。
  • onNextonErroronComplete 方法用于发射事件。
  • dispose 方法通过 DisposableHelper 进行订阅的管理。

Disposable.dispose() 切断消息

Disposable 用于管理订阅,可以通过 dispose() 方法取消订阅。以下是 CreateEmitter 中的 dispose() 方法:

@Override
public void dispose() {
    if (get() != DISPOSED) {
        Disposable d = getAndSet(DISPOSED);
        if (d != DISPOSED && d != null) {
            d.dispose();
        }
    }
}
  • dispose() 方法通过原子操作将当前状态设置为 DISPOSED,并调用实际的 Disposable 对象的 dispose() 方法。

线程切换源码

RxJava 提供了多个 Scheduler 用于线程切换。以下是 subscribeOn()observeOn() 的实现:

public final Observable<T> subscribeOn(Scheduler scheduler) {
    Objects.requireNonNull(scheduler, "scheduler is null");
    return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<>(this, scheduler));
}

public final Observable<T> observeOn(Scheduler scheduler) {
    Objects.requireNonNull(scheduler, "scheduler is null");
    return RxJavaPlugins.onAssembly(new ObservableObserveOn<>(this, scheduler, false, bufferSize()));
}
  • subscribeOn()observeOn() 都会创建对应的 ObservableSubscribeOnObservableObserveOn 对象,后者会在实际订阅时切换线程。

以下是 ObservableSubscribeOn 中的 subscribeActual() 方法:

@Override
protected void subscribeActual(final Observer<? super T> observer) {
    final SubscribeOnObserver<T> parent = new SubscribeOnObserver<>(observer);
    observer.onSubscribe(parent);
    parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
  • 创建 SubscribeOnObserver,这是 Observer 的一个装饰器。
  • 调用 Scheduler.scheduleDirect() 切换到指定线程执行订阅操作。

Scheduler

Scheduler 是 RxJava 中用于控制并发和线程的抽象类。它定义了将任务调度到不同线程的机制。以下是 Scheduler 的简化实现和线程切换原理:

public abstract class Scheduler {
    public abstract Worker createWorker();

    public Disposable scheduleDirect(Runnable run) {
        Worker w = createWorker();
        w.schedule(run);
        return w;
    }

    public static abstract class Worker implements Disposable {
        public abstract Disposable schedule(Runnable run);
    }
}
  • Scheduler 定义了 createWorker() 方法,用于创建 Worker 实例。
  • scheduleDirect() 方法将任务调度到 Worker 上执行。
  • Worker 是一个抽象类,定义了 schedule() 方法用于调度任务。

具体的 Scheduler 实现(如 Schedulers.io()Schedulers.computation())会提供不同的线程池和调度