RxJava2记录

1.先来一段最基本的调用

// 创建上游被观察者
Observable observable = Observable.create(new ObservableOnSubscribe() {
    @Override
    public void subscribe(ObservableEmitter e) throws Exception {
        Log.i(TAG, "ObservableEmitter, 上游发射数据:" + " currentThread = " + Thread.currentThread().getName());
        e.onNext(1);// 调用Observer的onNext
        e.onComplete();// 调用Observer的onComplete
    }
});
// 创建下游观察者
Observer observer = new Observer() {
    @Override
    public void onSubscribe(Disposable d) {
        // onSubscribe在调用subscribe的线程中执行
        // Disposable可以做切断操作,让Observer不再接收上游事件
        Log.i(TAG, "onSubscribe, 下游收到订阅,发生在上游发射数据之前: " + " currentThread = " + Thread.currentThread().getName());
    }

    @Override
    public void onNext(Integer integer) {
        Log.i(TAG, "onNext, 下游接收数据: " + " currentThread = " + Thread.currentThread().getName());
    }

    @Override
    public void onError(Throwable e) {
        Log.i(TAG, "onError, 下游收到异常: " + " currentThread = " + Thread.currentThread().getName());
    }

    @Override
    public void onComplete() {
        Log.i(TAG, "onComplete,  调用结束: " + " currentThread = " + Thread.currentThread().getName());
    }
};
// 订阅
observable.subscribe(observer);

日志打印如下:

I/RxJava2: onSubscribe, 下游收到订阅,发生在上游发射数据之前:  currentThread = main
I/RxJava2: ObservableEmitter, 上游发射数据: currentThread = main
I/RxJava2: onNext, 下游接收数据:  currentThread = main
I/RxJava2: onComplete,  调用结束:  currentThread = main

可以看出:

  • 下游观察者onSubscribe方法首先执行;
  • 然后上游被观察者的subscribe方法执行;
  • 最后下游观察者的onNext、onComplete执行。

分析一下这个过程,Observable.create创建了Observable对象,也就是ObservableCreate

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static  Observable create(ObservableOnSubscribe source) {
    ObjectHelper.requireNonNull(source, "source is null");
    return RxJavaPlugins.onAssembly(new ObservableCreate(source));// 钩子函数,直接返回ObservableCreate
}

调用subscribe时就调用了ObservableCreate的subscribe方法,ObservableCreate继承了Observable,就相当于调用了父类的subscribe方法,看一下Observable的subscribe方法

public abstract class Observable implements ObservableSource {   
    ...
    
    @SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(Observer observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);

            ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");

            subscribeActual(observer);// 这里调用了subscribeActual这个抽象方法
        } 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 observer);// 抽象方法,子类实现
    ...
}

这样就回到了ObservableCreate这个实现类,重点关注它的subscribeActual实现方法

public final class ObservableCreate extends Observable {
    final ObservableOnSubscribe source;

    public ObservableCreate(ObservableOnSubscribe source) {
        this.source = source;// 这是传入的就是我们create创建的匿名内部类ObservableOnSubscribe
    }

    @Override
    protected void subscribeActual(Observer observer) {// 传入观察者
        // 创建了CreateEmitter,这是一个静态内部类,它实现了ObservableEmitter和Disposable接口,就是上游发射数据的发射器
        CreateEmitter parent = new CreateEmitter(observer);
        observer.onSubscribe(parent);// 这里就调用了下游观察者的onSubscribe方法,所以日志打印时Observer的onSubscribe最先调用

        try {
            source.subscribe(parent);// 这里调用了ObservableOnSubscribe的subscribe方法,用来发射数据
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

    static final class CreateEmitter extends AtomicReference
    implements ObservableEmitter, Disposable {

        private static final long serialVersionUID = -3434801548987643227L;

        final Observer observer;

        CreateEmitter(Observer observer) {// 传入我们创建的下游观察者
            this.observer = observer;
        }

        @Override
        public void onNext(T t) {// 当上游调用e.onNext时,调用此方法
            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);// 调动了observer的onNext方法
            }
        }

        @Override
        public void onError(Throwable t) {// 当异常时调用此方法
            if (!tryOnError(t)) {
                RxJavaPlugins.onError(t);
            }
        }

        @Override
        public boolean tryOnError(Throwable t) {
            if (t == null) {
                t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
            }
            if (!isDisposed()) {
                try {
                    observer.onError(t);// 调用observer的onError方法
                } finally {
                    dispose();
                }
                return true;
            }
            return false;
        }

        @Override
        public void onComplete() {// 当上游调用e.onComplete时,调用此方法
            if (!isDisposed()) {
                try {
                    observer.onComplete();// 调用observer的onComplete方法
                } finally {
                    dispose();
                }
            }
        }
        ...
    }
    ...
}

上面就展示了最基本的从上游到下游中间的调用过程。

2.增加线程切换
先上代码

observable.subscribeOn(Schedulers.io())// 用于指定subscribe时所在的线程,就是发射事件的线程(指定多次,第一次为准)
                .observeOn(AndroidSchedulers.mainThread())//  用于指定下游Observer回调发生的线程,就是订阅者接收事件的线程。(可以指定多次)
                .subscribe(observer);

日志打印如下:

I/RxJava2: onSubscribe, 下游收到订阅,发生在上游发射数据之前:  currentThread = main
I/RxJava2: ObservableEmitter, 上游发射数据: currentThread =  RxCachedThreadScheduler-1
I/RxJava2: onNext, 下游接收数据:  currentThread = main
I/RxJava2: onComplete,  调用结束:  currentThread = main

可以看出:

  • 下游观察者onSubscribe方法执行在subscribe时的线程;
  • 上游被观察者的subscribe方法(也就是发射数据时的方法)执行在RxCachedThreadScheduler-1线程;
  • 下游观察者的onNext、onComplete都执行在主线程。

2.1现在分析线程切换的原理,首先看subscribeOn方法,返回了ObservableSubscribeOn

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable subscribeOn(Scheduler scheduler) {
    ObjectHelper.requireNonNull(scheduler, "scheduler is null");
    // this就是observable,scheduler就是传入的Schedulers.io
    return RxJavaPlugins.onAssembly(new ObservableSubscribeOn(this, scheduler));
}

继续看ObservableSubscribeOn,它继承了AbstractObservableWithUpstream

public final class ObservableSubscribeOn extends AbstractObservableWithUpstream {
    final Scheduler scheduler;

    public ObservableSubscribeOn(ObservableSource source, Scheduler scheduler) {
        super(source);// 1.保存上游的observable
        this.scheduler = scheduler;// 2.保存传入的线程调度器
    }

    @Override
    public void subscribeActual(final Observer s) {
        // 3.对下游Observer进行装饰
        final SubscribeOnObserver parent = new SubscribeOnObserver(s);
        // 4.首先调用下游observer的onSubscribe方法
        s.onSubscribe(parent);
        // 5.SubscribeTask是一个runnable,scheduler在指定的线程运行这个runnable,再将线程调度的Disposable赋值给当前的Disposable
        // 这里就实现了线程的切换了,run方法运行在scheduler的线程
        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }

    static final class SubscribeOnObserver extends AtomicReference implements Observer, Disposable {

        private static final long serialVersionUID = 8094547886072529208L;
        final Observer actual;

        final AtomicReference s;

        SubscribeOnObserver(Observer actual) {
            this.actual = actual;// 保存下游的observer
            this.s = new AtomicReference();
        }

        @Override
        public void onSubscribe(Disposable s) {
            DisposableHelper.setOnce(this.s, s);
        }

        @Override
        public void onNext(T t) {
            actual.onNext(t);// 通过装饰的SubscribeOnObserver,最终调用下游observer的onNext方法
        }

        @Override
        public void onError(Throwable t) {
            actual.onError(t);
        }

        @Override
        public void onComplete() {
            actual.onComplete();
        }
        ...
    }

    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver parent;

        SubscribeTask(SubscribeOnObserver parent) {
            this.parent = parent;// 保存下游observer的装饰对象
        }

        @Override
        public void run() {
            // 6.这里就在指定的scheduler线程调用下游装饰后的observer订阅上游observable的方法,
            // 相当于上面没有线程切换的状态,只是observer变成了装饰后的SubscribeOnObserver,
            // 调用的方法onSubscribe、onNext等就到了SubscribeOnObserver那,最终调用下游observer的
            source.subscribe(parent);
        }
    }
}

这里可以总结一下大致的流程

  • 调用subscribeOn时,将Obserable装饰成ObservableSubscribeOn,将Observer装饰成SubscribeOnObserver;在最初subscribe订阅的线程回调observer的onSubscribe方法;
  • 然后调用parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)))执行runnable实现线程切换,在scheduler线程run方法调用source.subscribe(parent),这里的parent SubscribeOnObserver就是装饰后的observer,最终调用observer的方法。

Scheduler的scheduleDirect方法

public abstract class Scheduler {
    ...
    @NonNull
    public Disposable scheduleDirect(@NonNull Runnable run) {// 这里传入的就是SubscribeTask
        return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
    }

    @NonNull
    public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
        // 这里的子类就是IoScheduler,创建的worker是EventLoopWorker
        final Worker w = createWorker();
        // hook方法,可以认为decoratedRun == run
        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
        // DisposeTask 实现了Runnable, Disposable
        DisposeTask task = new DisposeTask(decoratedRun, w);
        // 这里最终掉用了ThreadWorker的scheduleActual方法,切换到线程池中执行
        w.schedule(task, delay, unit);

        return task;
    }

    @NonNull
    public abstract Worker createWorker();// 抽象方法,子类实现
    ...
}

AbstractObservableWithUpstream

abstract class AbstractObservableWithUpstream extends Observable implements HasUpstreamObservableSource {

    /** The source consumable Observable. */
    protected final ObservableSource source;// Observable是ObservableSource实现类,所以可以看成是Observable

    /**
     * Constructs the ObservableSource with the given consumable.
     * @param source the consumable Observable
     */
    AbstractObservableWithUpstream(ObservableSource source) {
        this.source = source;// 构造方法,ObservableSubscribeOn中会调用
    }

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

AbstractObservableWithUpstream继承了Observable,通过source保存上游的Observable。

2.2再看observeOn方法

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable observeOn(Scheduler scheduler) {
    return observeOn(scheduler, false, bufferSize());
}

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
    ObjectHelper.requireNonNull(scheduler, "scheduler is null");
    ObjectHelper.verifyPositive(bufferSize, "bufferSize");
    return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, scheduler, delayError, bufferSize));
}

到这里可以猜想流程跟subscribeOn差不多,都是采用装饰者模式,分别对ObservableObserver装饰产生一个中间的被观察者和观察者,实现线程变换。

继续看ObservableObserveOn,这也是对Observable的装饰,它也继承了AbstractObservableWithUpstream

public final class ObservableObserveOn extends AbstractObservableWithUpstream {
    final Scheduler scheduler;
    final boolean delayError;
    final int bufferSize;
    public ObservableObserveOn(ObservableSource source, Scheduler scheduler, boolean delayError, int bufferSize) {
        super(source);// 1.保存上游装饰过的observable
        this.scheduler = scheduler;// 2.保存传入的线程调度器
        this.delayError = delayError;
        this.bufferSize = bufferSize;
    }

    @Override
    protected void subscribeActual(Observer observer) {
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            // 3.这里的子类就是HandlerScheduler,创建HandlerWorker
            Scheduler.Worker w = scheduler.createWorker();
            // 4.装饰下游observer,调用上游装饰的observable的subscribe方法
            // 上游observable执行subscribeActual,调用ObserveOnObserver的onSubscribe、onNext等方法
            source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
        }
    }
}

ObserveOnObserver的静态内部类ObserveOnObserver,上游observable执行subscribeActual方法,调用ObserveOnObserver的onSubscribe、onNext等方法

static final class ObserveOnObserver extends BasicIntQueueDisposable
implements Observer, Runnable {
    private static final long serialVersionUID = 6576896619930983584L;
    final Observer actual;
    final Scheduler.Worker worker;
    final boolean delayError;
    final int bufferSize;
    SimpleQueue queue;
    Disposable s;
    Throwable error;
    volatile boolean done;
    volatile boolean cancelled;
    int sourceMode;
    boolean outputFused;

    ObserveOnObserver(Observer actual, Scheduler.Worker worker, boolean delayError, int bufferSize) {
        this.actual = actual;// 下游observer
        this.worker = worker;// 调度工作者
        this.delayError = delayError;
        this.bufferSize = bufferSize;
    }

    @Override
    public void onSubscribe(Disposable s) {
        if (DisposableHelper.validate(this.s, s)) {
            this.s = s;
            if (s instanceof QueueDisposable) {// 一般为true
                @SuppressWarnings("unchecked")
                QueueDisposable qd = (QueueDisposable) s;
                int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);
                if (m == QueueDisposable.SYNC) {// 判断执行模式同步或者异步
                    sourceMode = m;
                    queue = qd;
                    done = true;// 标志为true,后面的onxx不会执行,直接return
                    actual.onSubscribe(this);
                    schedule();
                    return;
                }
                if (m == QueueDisposable.ASYNC) {
                    sourceMode = m;
                    queue = qd;
                    actual.onSubscribe(this);// 调用下游observer的onSubscribe
                    return;
                }
            }
            queue = new SpscLinkedArrayQueue(bufferSize);
            actual.onSubscribe(this);
        }
    }

    @Override
    public void onNext(T t) {
        if (done) {// 判断是否完成
            return;
        }

        if (sourceMode != QueueDisposable.ASYNC) {
            queue.offer(t);
        }
        schedule();// 开始调度 
    }

    @Override
    public void onError(Throwable t) {// 只执行一次
        if (done) {// 判断是否完成
            RxJavaPlugins.onError(t);
            return;
        }
        error = t;// 记录错误
        done = true;// 标志为true
        schedule();// 开始调度
    }

    @Override
    public void onComplete() {
        if (done) {// 判断是否完成
            return;
        }
        done = true;// 标志为true
        schedule();// 开始调度
    }
    ...
}

最终都调用了schedule方法,实现线程的切换

void schedule() {
    if (getAndIncrement() == 0) {
        worker.schedule(this);
    }
}

这里传入了this,因为ObserveOnObserver实现了Runnable接口,看它的run方法

@Override
public void run() {
    if (outputFused) {// 一般是false
        drainFused();
    } else {
        drainNormal();
    }
}

看drainNormal方法

void drainNormal() {
    int missed = 1;
    final SimpleQueue q = queue;
    final Observer a = actual;

    for (;;) {
        if (checkTerminated(done, q.isEmpty(), a)) {
            return;
        }

        for (;;) {
            boolean d = done;
            T v;

            try {
                v = q.poll();// 分发数据
            } catch (Throwable ex) {
                Exceptions.throwIfFatal(ex);// 异常终止
                s.dispose();
                q.clear();
                a.onError(ex);
                worker.dispose();
                return;
            }
            boolean empty = v == null;

            if (checkTerminated(d, empty, a)) {// 判断队列是否为空
                return;
            }

            if (empty) {// 空数据退出
                break;
            }

            a.onNext(v);// 下发数据给下游observer
        }

        missed = addAndGet(-missed);
        if (missed == 0) {
            break;
        }
    }
}
// 检查是否已终止
boolean checkTerminated(boolean d, boolean empty, Observer a) {
    if (cancelled) {// 已取消
        queue.clear();// 清空队列
        return true;
    }
    if (d) {// 这里是done
        Throwable e = error;
        if (delayError) {
            if (empty) {
                if (e != null) {
                    a.onError(e);
                } else {
                    a.onComplete();
                }
                worker.dispose();
                return true;
            }
        } else {
            if (e != null) {
                queue.clear();
                a.onError(e);
                worker.dispose();
                return true;
            } else
            if (empty) {
                a.onComplete();
                worker.dispose();
                return true;
            }
        }
    }
    return false;
}

总结

  • 创建任务链,每一步都会返回对应的Observable对象;
  • 逆向逐级订阅,每一步都会生成对应的Observer对上一步生成的Observable进行订阅;
  • 执行任务链,执行任务链之后,每一步都会通知对应的Observer,从而完成整调任务链。

你可能感兴趣的:(RxJava2记录)