Rxjava2原理流程+操作符+线程切换 浅析~

0.前言

没拜读过强大的代码就建议去稍微看一下rxjava2的原理,并不难懂。写的非常的好,也能领略到大佬写的代码有多么的强。里面的设计模式真的牛逼

1.Rxjava2

Rxjava2用于我们来做响应式编程模式的操作。用起来很简单,但是如果面试/其它场合下让你去写一些骚操作或者说其中的原理,真的蒙蔽的不行…然后去研读其代码,发现很多文章写的优点乱.让我有点理不清楚. 这就当算是我阅读源码的理解吧…

2.文章解决的问题.

  • RxJava2的基本运行流程
  • map操作符的运作
  • 线程切换原理

3.总图解

借助大佬的分析出来的图解,分析出流程图,这里颜色相同的代表同一对象.我们来一步一步慢慢看。
在这里插入图片描述

4.基本流程

 private void k(){
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Object> emitter) throws Exception {
                emitter.onNext(1);
            }
        }).subscribe(new io.reactivex.Observer<Object>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.d(TAG, "onSubscribe: ");
            }

            @Override
            public void onNext(@NonNull Object o) {
                Log.d(TAG, "onNext: "+o);
            }

            @Override
            public void onError(@NonNull Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

这一段代码应该非常熟悉了,我就不多讲了。
只知道结果
onSubscribe先被打印
onNext后被打印
OK,我们看下源码中间发生了什么。我们先从 Observable.create()进去看

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

RxJavaPlugins先不用去理解,我们要知道这里新建了一个ObservableCreate类,并且将我们外部新建的ObservableOnSubscribe类传入了进去。


然后我们再来看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);
        }
    }
    }
    ......

里面保存了我们外部创建的ObservableOnSubscribe类,并且有一个subscribeActual方法,我们先记住这个方法留下的伏笔.
很奇怪,它会调用吗?参数需要的Observer类又从哪里来?.我们暂时不知道.所以说,这个类暂时在这解析完毕.整一个create就只是将我们的外部类传进来,并返回Observable类对象,其实这个对象就是ObservableCreate类
ObservableCreate类继承Obserable类


我们来看我们使用的subscribe方法(Obserable类中的)

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

            ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");

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

将外部创建的Observe类传入,并且调用subscribeActual(observer)方法,传入的就是我们外部创建的Observe类!!!.subscribeActual类是抽象方法,那它的具体实现就在obserableXXX类内部。


这个时候我们回过头去看ObservableCreate类的subscribeActual()方法。你就会发现。

我们创建的Observer类被封装成CreateEmitter.并且调用该observer.onSubscribe()
这里回答了一个问题.OnSubscribe()永远是第一个开始调用的
然后调用了我们的source.subscribe()
即我们外部创建ObservableOnSubscribe类的subscribe(parent).
这里的parent.那就是我们外部接口中的Emit了…


OK,那我们来看Emitte的具体实现类CreateEmitter


    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(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
                return;
            }
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }
        }
        //...........后面还有很多

可以看到,一旦Emitter的onNext方法被使用.那么observer中的OnNext方法也被调用。


怎么样,基本流程应该被你搞通了.但是…不知道你能不能理解.里面涉及到的责任链模式以及增加的装饰器。它不像普通的责任链,是将上游的对象直接传送到下游,而是会封装成一个地方…
这里对流程稍微总结一句话,需要比较注重的理解它.

  • Obserable从上到下,一步步被保存为source.直到终点的.subscribe.
  • observer 从下到上,一步步被Obserable订阅
  • 在subscribeActua方法中不断调用subscribe(),而subscribe()又会不断调用subscribeActua

在这里插入图片描述

5.map操作符

  Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Object> emitter) throws Exception {
                emitter.onNext(1);
            }
        }).map(new Function<Object, Object>() {
            @Override
            public Object apply(@NonNull Object o) throws Exception {
                return null;
            }
        }).map(new Function<Object, Object>() {
            @Override
            public Object apply(@NonNull Object o) throws Exception {
                return null;
            }
        }).subscribe(new io.reactivex.Observer<Object>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull Object o) {

            }

            @Override
            public void onError(@NonNull Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

Ok,我们继续看下来.
一次Create,两次map.最后进行订阅.
create的我们就不分析了,我们进入到map的世界中.

    public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
    }

可以看到map和create是十分相似的,不过它构建的是ObserableMap类其中传入的Source为this.这里的this,就是Createable拉.Createable继承ObservableSource


我们看到ObservableMap类

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.subscribe(new MapObserver<T, U>(t, function));
    }
    //.......后面还有

这里看我们干的事情,在构建ObservableMap,会传入我们的this,即Obserable。所以你应该可以理解Obserable从上到下一步步被保存,并且存入我们的操作function.

然后我们熟悉的subscribeActual就到来啦。他只干一件事.
用source(obserable)去订阅一个Observer,这个Observer是ObservableMap类去构建的,参数需要Observer和function.

还记得这个吗?

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

            ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");

            subscribeActual(observer);

而Observer是从终点,我们自己创建的,所以你应该也能理解,observer 从下到上,一步步被Obserable订阅

map操作符应该更能体验rxjava2的整个构造,其中的让数据发生变化的地方你可以去理解一下MapObserver中的OnNext.我觉得更应该注重rxjava2的流程是如何发生的.这样有很多操作符,你都应该可以理解了。
在这里插入图片描述


6. 线程切换原理

线程切换使用subscribeOn方法.OK,我们来看看它

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

看到了吧,你干东西的入口都是一模一样的.看到这里应该对这个挺熟悉的了。


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> observer) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);

        observer.onSubscribe(parent);

        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }
    //后面还有很多

我们要看的是subscribeActual方法,这里应该就不用说了吧.

构造了一个SubscribeOnObserver类,并执行以下操作
1.封装成了SubscribeTask,其中run{}方法去进行的订阅
2.我们外部传入的参数scheduler利用方法scheduleDirect()执行该Task,方法内部即将Task让如Worker中.里面通过Handler去执行各种东西,细节自己看
3. parent.setDisposable我不是很懂是啥,希望大佬指教.

    public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
        final Worker w = createWorker();

        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

        DisposeTask task = new DisposeTask(decoratedRun, w);

        w.schedule(task, delay, unit);

        return task;
    }

而这里通常会有一问题出现,为什么subscribeOn()只有第一次有效?
因为传入的参数,对最后产生的Runable有影响!!!,而且订阅关系是从下往上的,所以自然而然只有第一次有效了.

7.总结:

基本流程是RxJava流由subscribe开始触发
并且不断的通过source.subscribe(observer)去触发subscribeActual().
而subscribeActual又是去订阅的.这样直到源头
才真正的开始执行到OnNext。
我们看源码需要注意的概念
Obserable
Observer
不断封装对象。
Obserable传递从上到下,
Observer订阅从下到上,最终获取拿到可操作的对象.

RxJava的代码看起来好像确实不是很难懂(迷惑),但是里面涉及到的设计模式很值得我们去学习…我只是稍微想看一下,但是发现这个源码太强了…值得学习留下自己一篇笔记…
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值