RxJava 1.x 源码浅析&操作符解析

RxJava已经用了很长一段时间了,从刚开始的迷迷糊糊observable,observer,subscriber傻傻搞不清楚,到后面会使用、用的顺手,一直到研究源码,过程也有点缓慢。不可置疑,RxJava是一个强大大大大的框架,熟悉了它的流式编程后,可以极大的简化你的代码复杂度。
本文主要解读RxJava的源码,不会探讨操作符的使用,不过作为举例,会带大家进入源码看observerOn()操作符的Java实现。
本文可以分为两个部分:

1、最简单的订阅事件

2、observerOn(AndroidScheduler.main())是怎么实现线程切换的

所以我们要明确源码中以下代码的调用而不是把源码从头看完

Observable.create(
                new Observable.OnSubscribe() {
                    @Override
                    public void call(Subscriber subscriber) {
                        subscriber.onNext(1);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber1);

subscriber1 = new Subscriber(){...}
1.1 Observable.create()

把observeOn()暂时忽略掉,也就是看看Observable.create()和Observable.subscribe()

//Observable.java

final OnSubscribe onSubscribe;
protected Observable(OnSubscribe f) {
        this.onSubscribe = f;
    }
public static  Observable create(OnSubscribe f) {
        return new Observable(RxJavaHooks.onCreate(f));
    }

create方法是一个静态方法,就像他的名字,就是new一个Observable对象,不可谓不简单。create方法接收的参数是OnSubscribe,熟悉的朋友都知道,OnSubscribe接口继承自Action1,也就是有个接受一个参数无返回的call方法:

//Action1.java
public interface Action1 extends Action {
    void call(T t);
}

那么回到上面create,RxJavaHooks.onCreate(f)又对OnSubscribe做了什么呢?

//RxJavaHooks.java

//这是成员变量
onObservableCreate = new Func1() {
            @Override
            public Observable.OnSubscribe call(Observable.OnSubscribe f) {
                //获得Observeable的执行Hook,今后observable的onCreate等类似生命周期的回调都会通知此Hook
                return RxJavaPlugins.getInstance().getObservableExecutionHook().onCreate(f);
            }
        };

public static  Observable.OnSubscribe onCreate(Observable.OnSubscribe onSubscribe) {
        Func1 f = onObservableCreate;
        if (f != null) {
            //简单的调用了onObservableCreate的call方法,call方法实现在上面
            return f.call(onSubscribe);
        }
        return onSubscribe;
    }
//RxJavaPlugins.java

private final AtomicReference observableExecutionHook = new AtomicReference();

public RxJavaObservableExecutionHook getObservableExecutionHook() {
        if (observableExecutionHook.get() == null) {
            //看看系统中有没有该实现
            Object impl = getPluginImplementationViaProperty(RxJavaObservableExecutionHook.class, System.getProperties());
            if (impl == null) {
                //使用默认实现
                observableExecutionHook.compareAndSet(null, RxJavaObservableExecutionHookDefault.getInstance());
            } else {
                observableExecutionHook.compareAndSet(null, (RxJavaObservableExecutionHook) impl);
            }
        }
        return observableExecutionHook.get();
    }

RxJavaHooks中对onSubscribe参数没有做什么实质的操作,只是类似一个总控制台,告诉他自身的RxJavaObservableExecutionHook对象一个observale已经create,而RxJavaObservableExecutionHook的默认实现中的onCreate是空实现,这里我们就不看了。
回到Observable.create()方法,也就是调用了构造函数,然后对this.onSubscribe赋值。到此Observable.create就走完了。

1.2 subscribe()

subscribe中做的是其实也特别简单,就是有异常就调用try catch然后丢给onError,没有就调用之前create时传入的onSubscribe的call()方法。subscribe最终调用的是Observable中的一个静态方法:

static  Subscription subscribe(Subscriber subscriber, Observable observable) {
        if (subscriber == null) {
            throw new IllegalArgumentException("subscriber can not be null");
        }
        if (observable.onSubscribe == null) {
            throw new IllegalStateException("onSubscribe function can not be null.");
        }
        //onStart就是在这里调用的
        subscriber.onStart();

        ......

        try {
            //约等于observable.onSubscribe.call(subscriber),call方法就是在这里被调用的
            RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
            return RxJavaHooks.onObservableReturn(subscriber);
        } catch (Throwable e) {
                ......
                try {
                    subscriber.onError(RxJavaHooks.onObservableError(e));
                } catch (Throwable e2) {
                    ...... 
                    throw r; // NOPMD
                }
            }
            return Subscriptions.unsubscribed();
        }
    }

在这里可以看到onStart最先在当前线程调用,紧接着try to call
observable.onSubscribe.call(subscriber)
这里的subscriber就是我们调用subscribe(Subscriber)传入的参数,如果出现异常就调用subscriber.onError().所以在onSubscribe中的call方法中调用的诸如Subscriber.onNext等也都是在这个时候执行的。

2.1observerOn的实现

回到最初的代码中,看看.observeOn(AndroidSchedulers.mainThread())方法里干了什么事。

//Observable.java
public final Observable observeOn(Scheduler scheduler) {
        return observeOn(scheduler, RxRingBuffer.SIZE);
    }

//最终调用
public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        if (this instanceof ScalarSynchronousObservable) {
            return ((ScalarSynchronousObservable)this).scalarScheduleOn(scheduler);
        }
        return lift(new OperatorObserveOn(scheduler, delayError, bufferSize));
    }

public final  Observable lift(final Operator operator) {
        return create(new OnSubscribeLift(onSubscribe, operator));
    }

这里有个lift方法,顾名思义就是转换的方法了。这个lift方法内部需要两样东西,一个是旧的onSubscribe(可以看成create时候new的那个)和一个opterator,然后它用这两个变量,去new出一个新的OnSubscribe丢给了create方法,那么目前我们可以断定,RxJava的转换操作都是经过lift方法来实现的,再lift方法内部,它重新调用create方法以旧的onSubscribe为参数产生一个新的Onservable对象,可以简单粗暴地理解为RxJava中你用过了n次lift方法(操作符其实都是用这个方法实现的),那么最终在整个过程中产生过n+1个Observable对象。那么好像秘密都在OnSubscribeLife这个类中了,看看它的实现:

public final class OnSubscribeLift implements OnSubscribe {
    final OnSubscribe parent;
    final Operator operator;
    public OnSubscribeLift(OnSubscribe parent, Operator operator) {
        this.parent = parent;
        this.operator = operator;
    }
    @Override
    public void call(Subscriber o) {
        try {
            Subscriber st = RxJavaHooks.onObservableLift(operator).call(o);
            try {
                st.onStart();
                parent.call(st);
            } catch (Throwable e) {
              ......
            }
        } catch (Throwable e) {
        ......
        }
    }
}

它把传入的旧的onSubscribe对象当成parent,在call调用的时候会先执行operator.call(Subscriber)得到一个新的Subscriber,如果按照我们文章开头贴出的那段简单代码中的调用,此时传入call的Subscriber其实就是subscriber1。那么我们在这里先暂定subscriber1为旧的subscriber,operator.call返回的st为新的subscriber,然后parent是第一次create时候new的OnSubscriber对象。先看看operator.call做了什么,那么我们应该去看lift方法传入的OperatorObserveOn的实现:

public final class OperatorObserveOn implements Operator {
    private final Scheduler scheduler;
    public OperatorObserveOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        this.scheduler = scheduler;
        this.delayError = delayError;
        this.bufferSize = (bufferSize > 0) ? bufferSize : RxRingBuffer.SIZE;
    }
    @Override
    public Subscriber call(Subscriber child) {
        if (scheduler instanceof ImmediateScheduler) {
            return child;//直接返回不做什么
        } else if (scheduler instanceof TrampolineScheduler) {
            return child;//直接返回不做什么
        } else {
            //剩余情况返回了一个ObserveOnSubscriber对象,下看面可以知道它继承自Subscriber,
            //而且new出来之后调了init就直接返回了,那么我们应该看看它的init
            //由于它是一个Subscriber,我们还需要看它的onNext等实现
            ObserveOnSubscriber parent = new ObserveOnSubscriber(scheduler, child, delayError, bufferSize);
            parent.init();
            return parent;
        }
    }

static final class ObserveOnSubscriber extends Subscriber implements Action0 {
        final Queue queue;
        final Scheduler.Worker recursiveScheduler;
        public ObserveOnSubscriber(Scheduler scheduler, Subscriber child, boolean delayError, int bufferSize) {
            this.child = child;
            this.recursiveScheduler = scheduler.createWorker();
            ......
            request(calculatedSize);
        }

        //做一些初始化操作,给childSubscriber设置Producer
        void init() {
            Subscriber localChild = child;
            localChild.setProducer(new Producer() {
                @Override
                public void request(long n) {
                    if (n > 0L) {
                        BackpressureUtils.getAndAddRequest(requested, n);
                        schedule();
                    }
                }
            });
            ......
        }

        @Override
        public void onNext(final T t) {
            if (isUnsubscribed() || finished) {
                return;
            }
            if (!queue.offer(NotificationLite.next(t))) {
                onError(new MissingBackpressureException());
                return;
            }
            schedule();
        }

        protected void schedule() {
            if (counter.getAndIncrement() == 0) {
                recursiveScheduler.schedule(this);
            }
        }

        @Override
        public void call() {
            final Queue q = this.queue;
            final Subscriber localChild = this.child;
            for (;;) {
                long requestAmount = requested.get();
                while (requestAmount != currentEmission) {
                    boolean done = finished;
                    Object v = q.poll();
                    boolean empty = v == null;
                    ......
                    localChild.onNext(NotificationLite.getValue(v));
                    .....
            }    
        }
}

上面我们讲过ObserveOnSubscriber被new出来后直接被返回,那么作为一个Subscriber,外部肯定会调用它的onNext方法来传递数据的,那么,正如我们所想的,onNext方法中每传入一个t,都会调用Queue.offer,如果成功进入schedule()调度,而在schedule方法中调用的是Scheduler.Worker.schedule()。这是个abstract方法,那么它在哪里实现呢?

2.2 AndroidSchedulers.mainThread()

这时候终于轮到它出面了,看看mainThread()方法:

public final class AndroidSchedulers {
    private static final AndroidSchedulers INSTANCE = new AndroidSchedulers();
    private final Scheduler mainThreadScheduler;

    private AndroidSchedulers() {
        RxAndroidSchedulersHook hook = RxAndroidPlugins.getInstance().getSchedulersHook();

        Scheduler main = hook.getMainThreadScheduler();
        if (main != null) {
            mainThreadScheduler = main;
        } else {
            mainThreadScheduler = new LooperScheduler(Looper.getMainLooper());//获得UI线程Loop
        }
    }

    public static Scheduler mainThread() {
        return INSTANCE.mainThreadScheduler;
    }
class LooperScheduler extends Scheduler {
    private final Handler handler;

    LooperScheduler(Looper looper) {
        handler = new Handler(looper);
    }

    @Override
    public Worker createWorker() {
        return new HandlerWorker(handler);
    }

    static class HandlerWorker extends Worker {
        private final Handler handler;

        HandlerWorker(Handler handler) {
            this.handler = handler;
            this.hook = RxAndroidPlugins.getInstance().getSchedulersHook();
        }

        @Override
        public Subscription schedule(Action0 action, long delayTime, TimeUnit unit) {
            if (unsubscribed) {
                return Subscriptions.unsubscribed();
            }

            action = hook.onSchedule(action);

            ScheduledAction scheduledAction = new ScheduledAction(action, handler);

            Message message = Message.obtain(handler, scheduledAction);
            message.obj = this; // Used as token for unsubscription operation.

            handler.sendMessageDelayed(message, unit.toMillis(delayTime));

            if (unsubscribed) {
                handler.removeCallbacks(scheduledAction);
                return Subscriptions.unsubscribed();
            }

            return scheduledAction;
        }

        @Override
        public Subscription schedule(final Action0 action) {
            return schedule(action, 0, TimeUnit.MILLISECONDS);
        }
      }

      static final class ScheduledAction implements Runnable, Subscription {
            private final Action0 action;

            ScheduledAction(Action0 action, Handler handler) {
                this.action = action;
                this.handler = handler;
            }

            @Override public void run() {
                try {
                    action.call();
                } catch (Throwable e) {
                    ......
                }
        }

在AndroidSchedule.mainThread()方法中,LooperScheduler的构造函数的参数是Loop.getMainLooper(),那么之前我们说的Scheduler.Worker.schedule()这个方法,就是LooperScheduler中的静态内部类HandlerWorker所实现的schedule()方法了,这个方法中把一个Runnbale Message丢给了handler,那么该Runable就会在handler所在的线程调用,而该Runnable中的run实现是调用了action0.call(),也就是前面看的ObserveOnSubscriber对象它实现的call方法,回过头去看,ObserveOnSubscriber.call调用了childSubscriber.onNext那这个childSubscriber是什么呢?

public final class OnSubscribeLift implements OnSubscribe {
    @Override
    public void call(Subscriber o) {
            Subscriber st = RxJavaHooks.onObservableLift(operator).call(o);
    }
}

没错,childSubscriber就是上面的对象o,也就是lift操作之后的subscriber,这也就是为什么我们说observerOn()调用后,下面写的所有map也好,subscribe也好,所有的onNext方法都在observerOn()指定的线程里调用。

总结

RxJava的流式编程最大的功臣非lift莫属了,但是他的实现非常简单,这给了我们很大的自定义operator的空间,不过就目前的操作符来看,基本需求都能覆盖了,所以自定义operator其实不是很建议的。RxJava的流式编程,其实就是基于java的函数回调OnSubscribe.call()方法,就比如文中的最简单的例子,create()的时候产生了一个onSubscribe1,observerOn()内部产生了onSubscribe2,最后在subscribe的时候,调用流程是这样的:

onSubscribe2.call(){//对比与示例中observerOn产生的
        onSubscribe1.call(){//对比与示例中create产生的
            //还有onSubscribe0等等。假设!!!,跟示例无关了。
            onSubscribe0.call(){
                //这是最开始create的onSubscribe,不是OnSubscribeLift
                doSomething
            }
            doSomething
        }
        doSomething
}

这就是RxJava的响应式编程.

你可能感兴趣的:(RxJava 1.x 源码浅析&操作符解析)