RxJava执行流程

核心问题:
- 为甚是被观察者订阅观察者
- RxJava执行的流程

为甚是被观察者订阅观察者

Observable.subscribe(Observer); 从字面上的理解是被观察者订阅观察者,比如报纸订阅了读者。但从开发者的角度来理解,就很正常 了。

RxJava这样设置的目的是为了流式Api的设计,还有就是Android中的观察者模式都是这样的写法,比如View.setOnClickListener(OnClickListener) : View就是被观察者,OnClickListener是观察者,他们通过setOnClickListener形成订阅关系。 一旦被观察者发生了什么事情(事件),就需要告知观察者,然后观察者会做出相应的措施。

RxJava执行的流程

从一个简单的示例代码说起:

 Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onComplete();
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Integer>() {
                    private Disposable mD = null;

                    @Override
                    public void onSubscribe(Disposable d) {
                        mD = d;
                    }

                    @Override
                    public void onNext(Integer value) {
                        if (1 == value) {
                            mD.dispose();
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        KLog.d("e:" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        KLog.d("onComplete");
                    }
                });

按照自上而下的顺序,开始吧

Observable.create(ObservableOnSubscribe source)
   public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }

流程的第一步,创建了两个对象:ObservableOnSubscribe 和 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<T>(observer);
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

    //省略其他代码

}

ObservableCreate 继承Observable,在构造函数中保存了上一级创建的 ObservableOnSubscribe 对象的引用。

public abstract class Observable<T> implements ObservableSource<T>{...}
public interface ObservableSource<T> {

    void subscribe(Observer<? super T> observer);
}

上面的2段源码清楚的看到,Observable 是一个抽象类,是 ObservableSource 的实现类,而 ObservableSource 类是一个接口,它表示事件源。内部只有一个方法 subscribe 该方法表示通过 Observer 订阅当前的事件源。那么事件发布的事件,在 Observer 订阅者中就会被收到。了解了 Observable 的顶层接口之后,我们就知道该体系最重要的一个功能那就是 subscribe 方法了,因此我们就重点关注子类的 subscribe 方法。

现在,把视角转到Observable的subscribe()方法来,看看它做了什么处理。

 public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);

            ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
            //这段代码是核心代码
            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // can't call onError because no way to know if a Disposable has been set or not
            // can't call onSubscribe because the call might have set a Subscription already
            RxJavaPlugins.onError(e);

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
            npe.initCause(e);
            throw npe;
        }
    }


     protected abstract void subscribeActual(Observer<? super T> observer);

他把observer订阅者传递给subscribeActual(Observer observer)抽象方法,这意味着所有Observable的子类,我们只要关心 subscribeActual(observer); 这个方法就好的。

好的,那么我们就回到最开始的ObservableCreate,去看看他在subscribeActual()做了什么

   @Override
    protected void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

在上面的代码里面,先是创建了一个发射器CreateEmitter,然后回调给 observer#onSubscribe() ,最后是通知上一级的Observable(也就是代码里的source)你可以发送事件了。这边不太了解RxJava可能有疑问我为什么这么下定论?因为事件是在被观察者“订阅”观察者时后才发送的!!!

subscribeOn(Schedulers.io())

这个方法的作用是让上游事件切换线程的,不管它在整个流中使用了几次,只有第一次是有效的。why? 先把这个疑问放下,后面看看流程图就应该明白了。

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

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() {
                source.subscribe(parent);
            }
        }));
    }
    //省略部分代码

}

是不是很熟悉,因为AbstractObservableWithUpstream也是继承自Observable。subscribeActual()方法里执行的也是相似的逻辑,只不过是多了scheduler线程相关的逻辑,这里先不进行详细分析。

abstract class AbstractObservableWithUpstream<T, U> extends Observable<U> implements HasUpstreamObservableSource<T> {

    /** The source consumable Observable. */
    protected final ObservableSource<T> source;

    /**
     * Constructs the ObservableSource with the given consumable.
     * @param source the consumable Observable
     */
    AbstractObservableWithUpstream(ObservableSource<T> source) {
        this.source = source;
    }

    @Override
    public final ObservableSource<T> source() {
        return source;
    }

}

这个抽象类也是保存了上一个Observable的引用。

observeOn(AndroidSchedulers.mainThread())

我猜这边应该是相似的代码。

public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;
    final boolean delayError;
    final int bufferSize;
    public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
        super(source);
        this.scheduler = scheduler;
        this.delayError = delayError;
        this.bufferSize = bufferSize;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            Scheduler.Worker w = scheduler.createWorker();

            source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
        }
    }

    //省略相关代码
}

果不其然,就不赘述了。

subscribe(Observer observer)

subscribe后,被观察者(Observable)一旦有发射什么事件,观察者(Observer)都可以接收事件。

总结

过程:断点调试,绘制流程图

rx流程图

还记得在介绍 #subscribeOn(Schedule)方法提出的那个问题?

无论我们在整个上游的事件流中使用了多少次#subscribeOn(Schedule)变换线程,只有第一次设置的有效。看了上面的流程图,相信应该明白了吧。

下一篇,讲述RxJava线程切换原理

### 关于 RxJava 的使用指南和教程 #### 什么是 RxJavaRxJava 是一种基于响应式编程(Reactive Programming)的库,用于处理异步数据流。它通过观察者模式简化了复杂的异步操作,并提供了丰富的操作符来组合、转换和过滤数据流。 --- #### RxJava 的基本概念 RxJava 的核心组件包括以下几个部分: - **Observable/Flowable**: 数据源,表示可被订阅的数据流。 - **Observer/Subscriber**: 订阅者,接收来自 Observable 或 Flowable 的通知。 - **onNext()**: 接收正常的数据项。 - **onError()**: 处理错误情况。 - **onComplete()**: 表示数据流结束[^2]。 --- #### 如何开始使用 RxJava? ##### 添加依赖 要使用 RxJava,在项目的 `build.gradle` 文件中添加以下依赖: ```gradle implementation 'io.reactivex.rxjava3:rxjava:3.1.5' implementation 'io.reactivex.rxjava3:rxandroid:3.0.0' ``` 注意:上述版本号可能随时间更新,请查阅官方文档获取最新版本[^4]。 --- #### 基本使用方式 ###### 方法一:分步骤实现 这是为了深入了解 RxJava 的工作原理。以下是具体的步骤: 1. 创建一个 Observable 对象。 2. 定义 Observer 来监听事件。 3. 调用 subscribe() 方法将两者连接起来。 代码示例: ```java // 步骤1:创建Observable对象 Observable<String> observable = Observable.just("Hello", "World"); // 步骤2:定义Observer Observer<String> observer = new Observer<String>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(String value) { System.out.println(value); } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onComplete() { System.out.println("Completed"); } }; // 步骤3:建立订阅关系 observable.subscribe(observer); ``` ###### 方法二:链式调用 这种方式更适合实际项目中的简洁性和高效性。可以通过链式调用来完成复杂的操作: 代码示例: ```java Observable.just("Hello", "World") .map(s -> s.toUpperCase()) // 将字符串转为大写 .subscribe(System.out::println); // 输出结果 ``` --- #### 组合与合并操作符详解 RxJava 提供了许多强大的操作符来帮助开发者灵活地处理数据流。常见的组合与合并操作符如下: 1. **merge():** 合并多个 Observables 并保持顺序不固定[^1]。 ```java Observable.merge(Observable.just(1, 2), Observable.just(3, 4)) .subscribe(System.out::println); ``` 2. **concat():** 类似 merge,但会按顺序依次发射数据。 ```java Observable.concat(Observable.just(1, 2), Observable.just(3, 4)) .subscribe(System.out::println); ``` 3. **zip():** 将多个 Observables 发射的数据按照指定的方式组合在一起。 ```java Observable.zip( Observable.just("A", "B"), Observable.just("C", "D"), (s1, s2) -> s1 + "-" + s2) .subscribe(System.out::println); ``` --- #### Retrofit 结合 RxJava 使用 Retrofit 和 RxJava 可以很好地配合使用,从而简化网络请求流程。首先需要配置 Retrofit 支持 RxJava: 代码示例: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); // 定义接口 interface ApiService { @GET("/data") Observable<List<Data>> getData(); } ApiService apiService = retrofit.create(ApiService.class); // 执行请求 apiService.getData().subscribe(dataList -> { dataList.forEach(item -> System.out.println(item)); }, throwable -> { throwable.printStackTrace(); }); ``` --- #### 更多资源推荐 如果想进一步学习 RxJava,可以参考以下资料: - Carson_Ho 的《Android RxJava 实际应用教学》[^3]。 - 一份详细的 RxJava 学习指南[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值