源码分析Rxjava2是如何完成链式调用的

这篇文章讲的不是如何使用 Rxjava2 , 而是通过我们常用的操作符来分析它是如何完成链式调用以及线程调度
Observable.just("123")
                .map(new Function<String, Integer>() {
                    @Override
                    public Integer apply(@NonNull String s) throws Exception {
                        (1)
                        return Integer.parseInt(s);
                    }})
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        (2)
                    }
                });

假设这段代码是在主线程执行的 , 那么很显然(1)是在子线程中进行(2)是在主线程中执行 , 大家有没有想过如果我将 subscribeOn() 和 observeOn() 换过来它的结果还是和上面一样的 , 这是如何实现的呢 ?
开始之前给大家抛出一个问题如果我将 map() 操作写在 observeOn() 方法下面情况是什么样的呢 ?


看源码之前我先从栗子开始
这里写图片描述

有一名老板 , 想试试手底下技术们的实例 , 就叫了一个手底下的一名程序员 , 给了他1000块钱 , 说 : 我给你一千 , 等我叫你行动的时候我再给你个手机 , 你到时候拿手机拍下1000块钱就可以了(先从简单开始) .

public class Programmer{
    String money;

    Programmer(String money) {
        this.money = money;
    }

    void programmerAction(Phone phone) {
        phone.takePhoto(money);
    }

    //手机
    interface Phone {
        void takePhoto(String money);
    }
}
Programmer programmer = new Programmer("1000RMB");
        programmer.programmerAction(new Programmer.Phone() {
            @Override
            public void takePhoto(String money) {
                Log.i("TAG", "takePhoto: " + money);
            }
        });

Log : 1000RMB

这块代码转到Rxjava会是什么样的呢

//程序员 = Observable.just("1000RMB")的返回值
Observable.just("1000RMB")
                //subscribe() 相当于程序员的 programmerAction()方法
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(@NonNull String s) throws Exception {
                        Log.i("TAG", "accept: " + s");
                    }
                });

老板 : 做的不错 , 那我在给你1000块钱 , 你给我拍个金条出来啊 .
程序员懵逼了 , 赶紧去找CTO .
CTO找到老板 .
CTO : 没问题啊 , 只要你给我一个变幻的规则 , 啥都给你变出来

public class CTO {
    //程序员
    Programmer programmer;
    //司令告诉CTO的变幻规则
    ChangeListener changeWay;

    public CTO(Programmer programmer , ChangeListener changeWay){
        this.programmer = programmer;
        this.changeWay = changeWay;
    }

    //CTO执行行动
    void ctoAction(Phone phone){
        //CTO把老板给自己的手机外包裹了一层黑科技
        CTOPhone listener = new CTOPhone(phone, changeWay);
        //之后叫年轻的程序员说: 你用这个拍老板给你的钱就可以了
        programmer.programmerAction(listener);
    }

    //黑科技手机
    class CTOPhone implements Phone{

        Phone phone;
        ChangeListener changeWay;
        //传入老板的手机和 , 变幻规则
        public CTOPhone(Phone phone, ChangeListener changeWay) {
            this.phone = phone;
            this.changeWay = changeWay;
        }

        @Override
        public void takePhoto(String money) {
            //把黑科技手机拍到的钱以老板定出的规则 , 变幻出金条
            String jintiao = changeWay.change(money);
            //之后让金条显示在老板给的手机的屏幕上
            phone.takePhoto(newWeapon);
        }
    }

    interface ChangeListener{
        String change(String money);
    }

}
Programmer programmer = new Programmer("1000RMB");
        programmer.programmerAction(new Programmer.Phone() {
            @Override
            public void takePhoto(String money) {
                Log.i("TAG", "takePhoto: " + money);
            }
        });
        CTO cto = new CTO(programmer, new CTO.ChangeListener() {
            @Override
            public String change(String money) {
                if (money.equals("1000RMB")){
                    return "金条";
                }
                return money;
            }
        });
        cto.ctoAction(new Programmer.Phone() {
            @Override
            public void takePhoto(String money) {
                Log.i("TAG", "takePhoto: " + money);
            }
        });

Log : 金条

咱们在把他转换成Rxjava中的函数 :

//老板给程序员1000块钱 , 程序员 = Observable.just("1000RMB")的返回值
Observable.just("1000RMB")
                //老板把规则和拿着1000块钱的程序员给了CTO
                //CTO = .map()后的返回值
                //这里map()只有一个参数 , 对应上面例子的变幻规则 , 至于程序员什么时候给了cto , 待会下面分析下源码
                .map(new Function<String, String>() {
                    @Override
                    public String apply(@NonNull String s) throws Exception {
                        if (s.equals("1000RMB")){
                            return "金条";
                        }
                        return s;
                    }})
                    //subscribe()老板让CTO行动
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(@NonNull String s) throws Exception {
                        Log.i("TAG", "accept: " + s);     
                    }
                });

这里写图片描述

之后年轻的程序员和CTO就会升职加薪、当上总经理、出任CEO、迎娶白富美、走上人生巅峰!

到这里你是否看明白了呢 , 上面的例子只是链式调用了两次 , 栗子中手机是观察者 , CTO和程序员是被观察者 .

该分析下源码了 , 可能看源码会更清晰一些 . 就先看一下just()和map()的源码吧

Observable.just("123")
                .map(new Function<String, Integer>() {
                    @Override
                    public Integer apply(@NonNull String s) throws Exception {
                        return Integer.parseInt(s);
                    }
                }).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
            }
            @Override
            public void onNext(@NonNull Integer integer) {
            }
            @Override
            public void onError(@NonNull Throwable e) {
            }
            @Override
            public void onComplete() {
            }
        });

咱们先看一下subscribe()方法

public final void subscribe(Observer<? super T> observer) {
            ......
            //该方法是Observable的抽象方法 , 所有继承了Observable的类都会实现
            //这个方法很重要 , 因为后面有很多继承Observable的类
            subscribeActual(observer);
}

ok , 只要记住subscribe()方法会调用subscribeActual();方法就可以啦 .

那咱们逐行看一下just()方法

public static <T> Observable<T> just(T item) {
        //判空
        ObjectHelper.requireNonNull(item, "The item is null");
        //RxjavaPlugins类是用于方便开发者hook用的 , 如果你不考虑hook
        //可以看成是 return new ObservableJust<T>(item);
        return RxJavaPlugins.onAssembly(new ObservableJust<T>(item));
    }

Rxjava2现在是不能传空了 , 否则会抛出异常 , 详细介绍请看下
Rxjava What’s different in 2.0

//继承了Observable被观察者 , 并且重写了subscribeActual()方法
public final class ObservableJust<T> extends Observable<T> implements ScalarCallable<T> {

    private final T value;
    public ObservableJust(final T value) {
        this.value = value;
    }

    @Override
    protected void subscribeActual(Observer<? super T> s) {
        //ScalarDisposable实现了Runnable类 , 将Observer类包装了进去
        ScalarDisposable<T> sd = new ScalarDisposable<T>(s, value);
        s.onSubscribe(sd);
        //这里调用了run()方法 , 那么看看run()方法的具体实现
        sd.run();
    }

    @Override
    public T call() {
        return value;
    }
}
public static final class ScalarDisposable<T> implements Runnable{

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

        @Override
        public void run() {
           ...
           //调用了观察者的onNext();
           //那么这里的observer是不是你subscribe()时传过来的observer呢? 接着看
           observer.onNext(value);
        }

}

这个类比较简单 , 先记住Observable.just(“123”)方法返回的就是ObservableJust这个类 .

在看一下map()方法

public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
        //判空
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        //无视RxJavaPlugins类 , 看成是 retrun new ObservableMap<T, R>(this, mapper);
        return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
    }

敲黑板

注意这里传过去的 this 参数 , 上面just()方法返回了ObservableJust类的对象 , 那么这个this就是ObservableJust对象啦 .

public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    final Function<? super T, ? extends U> function;

    public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
        super(source);
        this.function = function;
    }

    @Override
    public void subscribeActual(Observer<? super U> t) {
        //大家可以看到这里直接调用了source(就是上面ObservableJust对象)的subscribe()方法
        //可以看成直接调用了ObservableJust类的subscribeActual()方法
        source.subscribe(new MapObserver<T, U>(t, function));
    }
}

但是这里的Observer对象又被包装成了MapObserver类了 , 哈哈 , 所以上面 run() 中的 observer 其实就是MapObserver , 接着看一下

//BasicFuseableObserver实现了Observer类 , 所以可以把MapObserver类看成是Observer类
static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {  
        final Function<? super T, ? extends U> mapper;

        MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
            super(actual);
            this.mapper = mapper;
        }       
        @Override

        public void onNext(T t) {
            ...
            U v;
            try {
            //v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");(这是源码 , 进行了判空操作 , 大家就看下面代码就可以了)
            //mapper就是咱们自己写的转换器
            v = mapper.apply(t);
            } catch (Throwable ex) {
                fail(ex);
                return;
            }
            //actual就是被包装进来的Observer , 也就是咱们subscribe()是自己写的observer
            //上面进行转换之后把转换之后的值给传了进来
            actual.onNext(v);
        }
}

至此上面的代码分下到了map()阶段 , 那么掉用subscribe()之后呢 就会调用ObservableMap的subscribeActual()方法啦 , 里面又调用了ObservableJust的subscribeActual() . 但是注意 , 他们在来回调用之前会把Observer包装起来 , 也就是上面栗子中的把老板手机包装到了一个黑科技手机当中 .

觉得有点绕的话 上图!!

这里写图片描述

不管多少个链式调用也是跟这个是一样的 , subscribe()执行后 , 从最底层开始将你的Observer包装 , 在调用上层的subscribe() , 这一层在包装一下下层包装过的Observer发到上一层 , 直到最顶层 , 当调用onNext()的时候跟剥卷心菜似的先剥二楼的在剥三楼的 , 在剥到最底层也就是你传的observer的onNext()方法

至于线程调度的话其实也差不多的 , 之前Rxjava1.x版本把背压放在Observable处理 , 现在Rxjava2把背压转到Flowable之后Observable的源码易读多了 , 大家如果理解原理的话也可以试着看一下 . 这里先上一波草图 .
这里写图片描述

关于背压的文章请参考
关于 RxJava 背压

这篇文章至此结束 , 下次如果有时间会自己实现一个照着Rxjava自己实现一个简单包括线程调度的响应式编程代码 .

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值