RxJava2源码解析

本文为博主原创文章,转载请注明出处

前言

本文简析 RxJava2subscribeOnzip 操作符。

术语解释

Single.just().map().flatMap().subscribeOn().observeOn().subscribe();

上述代码中,Singlesubscribe() 之间的都称为 操作符,想像一下自己就是其中一个 操作符,那么位于左边的便称为 上游,位于右边的则称为 下游,故上下游其实是相对的。

源码分析指南

由于 RxJava 是链式调用,链条长度没有限制,所以源码分析需要技巧,直接从头看到尾,容易看的头晕。所以建议先写一个『最短的调用链』去分析,然后举一反三,推测其设计思想(仔细想想就知道,那么多操作符,肯定不需要每个都去分析,也不现实,所以只要理解其设计思想就行了)。

首先,我们需要明确每一次操作符调用的返回类型是什么:subscribe() 左边都是观察者的上游,而观察者的上游肯定是被观察者。所以每一次操作符调用的返回类型都是被观察者(而且每次都返回一个新的被观察者,内部持有对上一个观察者的引用)。鉴于 RxJava 的被观察者类型较多,有:

背压:上游数据发射太快,下游来不及处理,导致缓冲区溢出(类比我国人民都知道的水缸进水、放水问题)

本文仅以 io.reactivex.Single为例进行分析,其他类型举一反三即可,此处先给出对象引用关系图,根据此图即可推出函数调用轨迹:

2722938-c9b33acd78765c79.jpg
对象引用关系

源码分析都写在注释里了,subscribeOn 操作符是对 java 并发框架和 Android Handler 的封装,zip 操作符则是利用 java 原子类实现的。

一、subscribeOn

demo

        // Case2: 在非UI线程执行并关注结果
        Single.fromCallable(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return generateRandom();
            }
        }).subscribeOn(Schedulers.io()).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Logger.d(TAG, "test: accept(Integer integer) invoked on %s", Thread.currentThread().getName());
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                Logger.d(TAG, "test: accept(Throwable throwable) invoked on %s", Thread.currentThread().getName());
            }
        });

fromCallable(Callable callable) [-> Single.java]

    public static <T> Single<T> fromCallable(final Callable<? extends T> callable) {
        ObjectHelper.requireNonNull(callable, "callable is null");
        // RxJavaPlugins 里是全局钩子函数,分析源码时无视即可,此处就是返回 SingleFromCallable
        return RxJavaPlugins.onAssembly(new SingleFromCallable<T>(callable));
    }

RxJavaPlugins 里是全局钩子函数,无需关注

SingleFromCallable [-> SingleFromCallable.java]

// 注意继承自 Single,而 Single 实现了 SingleSource 接口,所以也继承了 subscribe() 方法
public final class SingleFromCallable<T> extends Single<T> {
    // 回调函数
    final Callable<? extends T> callable;

    public SingleFromCallable(Callable<? extends T> callable) {
        // 保存为全局变量
        this.callable = callable;
    }

    @Override
    protected void subscribeActual(SingleObserver<? super T> observer) {
        // 一个 run() 方法体为空的 RunnableDisposable 对象,用来取消订阅
        Disposable d = Disposables.empty();
        // 调用下游(本示例此处为SubscribeOnObserver)的 onSubscribe()
        observer.onSubscribe(d);

        // 已取消订阅的,直接返回,不会发射任何值
        if (d.isDisposed()) {
            return;
        }

        T value;
        try {
            // 调用 callable.call() 获取值
            value = ObjectHelper.requireNonNull(callable.call(), "The callable returned a null value");
        } catch (Throwable ex) {
            // 捕获所有异常,所以使用 rxjava 时,自己写的方法收不到异常通知,需订阅一个 Consumer<Throwable>
            Exceptions.throwIfFatal(ex);
            if
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值