RxJava(三)

Android知识总结

一、调度器 Scheduler

如果你想给Observable操作符链添加多线程功能,你可以指定操作符(或者特定的Observable)在特定的调度器(Scheduler)上执行。

使用ObserveOn和SubscribeOn操作符,你可以让Observable在一个特定的调度器上执行,ObserveOn指示一个Observable在一个特定的调度器上调用观察者的onNext, onError和onCompleted方法,SubscribeOn更进一步,它指示Observable将全部的处理过程(包括发射数据和通知)放在特定的调度器上执行。

Scheduler为调度器,也可以叫做线程控制器。RxJava通过它来指定每一段代码在那个线程中运行。在不指定线程的情况下,RxJava遵循线程不变的原则,即:在那个线程调用subscribe(),就在那个线程生产事件;在那个线程生产事件,就在那个线程消耗事件。如果需要切换线程,就需要使用Scheduler来进行控制。
Flowable 很多操作符内部都使用了背压策略, 从而避免过多的数据填满内部的队列. (Flowable 的默认队列是 128)。

1.1、 调度器的种类

下表展示了RxJava中可用的调度器种类:

  • Schedulers.computation( ): 用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io()),否则 I/O 操作的等待时间会浪费 CPU;默认线程数等于处理器的数量 。

  • Schedulers.from(executor) 使用指定的Executor作为调度器。

  • Schedulers.immediate( )在当前线程立即开始执行任务,相当于不指定线程。这是默认的 Scheduler。

  • Schedulers.io( ):用于IO密集型任务, 如:(读写文件、读写数据库、网络信息交互等)。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,大量的I/O调度操作将创建许多个线程并占用内存,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io( )默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器 。

  • Schedulers.newThread( ):为每个任务创建一个新线程,并在新线程执行操作。

  • Schedulers.trampoline( ) :当其它排队的任务完成后,在当前线程排队开始执行。

  • AndroidSchedulers.mainThread():它指定的操作将在 Android 主线程运行。主要用于Android的UI更新操作。

1.2、SubscribeOn

        Observable
                .create(new ObservableOnSubscribe() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter emitter) throws Exception {
                        //io 线程
                        emitter.onNext(11);
                        emitter.onComplete();
                    }
                })
                //步骤二
                .subscribeOn(
                        //步骤一
                        Schedulers.io())
                .subscribe(new Observer() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        //调用者的线程
                    }
                    @Override
                    public void onNext(@NonNull Integer integer) {
                        //io 线程
                    }
                    @Override
                    public void onError(@NonNull Throwable e) { }
                    @Override
                    public void onComplete() { }
                });
    }

根据上面代码和试图可以看到SubscribeOn主要用于上游事件线程的切换。
下面我们根据源码进行分析:

1.2.1、步骤一分析

    @onNull
    public static Scheduler io() {
        return RxJavaPlugins.onIoScheduler(IO);
    }

Schedulers类中我们可以看到调度器定义的IO操作。

    @NonNull
    static final Scheduler SINGLE;
    //用于计算任务
    @NonNull
    static final Scheduler COMPUTATION;
    //用于IO密集型任务
    @NonNull
    static final Scheduler IO;
    //当其它排队的任务完成后,在当前线程排队开始执行
    @NonNull
    static final Scheduler TRAMPOLINE;
    //为每个任务创建一个新线程
    @NonNull
    static final Scheduler NEW_THREAD;

    static final class SingleHolder {
        static final Scheduler DEFAULT = new SingleScheduler();
    }

    static final class ComputationHolder {
        static final Scheduler DEFAULT = new ComputationScheduler();
    }

    static final class IoHolder {
        static final Scheduler DEFAULT = new IoScheduler();
    }

    static final class NewThreadHolder {
        static final Scheduler DEFAULT = new NewThreadScheduler();
    }

    static {
        SINGLE = RxJavaPlugins.initSingleScheduler(new SingleTask());
        COMPUTATION = RxJavaPlugins.initComputationScheduler(new ComputationTask());
        //IO 线程的创建
        IO = RxJavaPlugins.initIoScheduler(new IOTask());
        TRAMPOLINE = TrampolineScheduler.instance();
        NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new NewThreadTask());
    }

RxJavaPlugins.initIoScheduler() 方法执行

    @NonNull
    public static Scheduler initIoScheduler(@NonNull Callable defaultScheduler) {
        ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can't be null");
        //运用 HOOK 可以统计 IO 创建次数
        Function, ? extends Scheduler> f = onInitIoHandler;
        if (f == null) {
            return callRequireNonNull(defaultScheduler);
        }
        return applyRequireNonNull(f, defaultScheduler);
    }

HOOK的使用

        RxJavaPlugins.setInitIoSchedulerHandler(new Function, Scheduler>() {
            @Override
            public Scheduler apply(Callable schedulerCallable) throws Exception {
                Log.d(TAG, "apply: 全局 监听 init scheduler:" +schedulerCallable.call());
                return schedulerCallable.call();
            }
        });

new IOTask()的创建

    static final class SingleHolder {
        static final Scheduler DEFAULT = new SingleScheduler();
    }

    static final class ComputationHolder {
        static final Scheduler DEFAULT = new ComputationScheduler();
    }

    static final class IoHolder {
        static final Scheduler DEFAULT = new IoScheduler();
    }

    static final class NewThreadHolder {
        static final Scheduler DEFAULT = new NewThreadScheduler();
    }


    static final class IOTask implements Callable {
        @Override
        public Scheduler call() throws Exception {
            return IoHolder.DEFAULT;
        }
    }

    static final class NewThreadTask implements Callable {
        @Override
        public Scheduler call() throws Exception {
            return NewThreadHolder.DEFAULT;
        }
    }

    static final class SingleTask implements Callable {
        @Override
        public Scheduler call() throws Exception {
            return SingleHolder.DEFAULT;
        }
    }

    static final class ComputationTask implements Callable {
        @Override
        public Scheduler call() throws Exception {
            return ComputationHolder.DEFAULT;
        }
    }

我们再看new IoScheduler()里面做些什么

    // 线程池的 factory,给每个新建的线程设置一个具有识别度的线程名
    static final RxThreadFactory WORKER_THREAD_FACTORY;
    //线程池
    static final CachedWorkerPool NONE;
    static {
        SHUTDOWN_THREAD_WORKER = new ThreadWorker(new RxThreadFactory("RxCachedThreadSchedulerShutdown"));
        SHUTDOWN_THREAD_WORKER.dispose();

        int priority = Math.max(Thread.MIN_PRIORITY, Math.min(Thread.MAX_PRIORITY,
                Integer.getInteger(KEY_IO_PRIORITY, Thread.NORM_PRIORITY)));

        WORKER_THREAD_FACTORY = new RxThreadFactory(WORKER_THREAD_NAME_PREFIX, priority);

        EVICTOR_THREAD_FACTORY = new RxThreadFactory(EVICTOR_THREAD_NAME_PREFIX, priority);
        //创建线程池
        NONE = new CachedWorkerPool(0, null, WORKER_THREAD_FACTORY);
        NONE.shutdown();
    }

    public IoScheduler() {
        this(WORKER_THREAD_FACTORY);
    }

CachedWorkerPoolIoScheduler的内部类

    static final class CachedWorkerPool implements Runnable {
        private final long keepAliveTime;
        private final ConcurrentLinkedQueue expiringWorkerQueue;
        final CompositeDisposable allWorkers;
        private final ScheduledExecutorService evictorService;
        private final Future evictorTask;
        private final ThreadFactory threadFactory;

        CachedWorkerPool(long keepAliveTime, TimeUnit unit, ThreadFactory threadFactory) {
            this.keepAliveTime = unit != null ? unit.toNanos(keepAliveTime) : 0L;
            this.expiringWorkerQueue = new ConcurrentLinkedQueue();
            this.allWorkers = new CompositeDisposable();
            this.threadFactory = threadFactory;

            ScheduledExecutorService evictor = null;
            Future task = null;
            if (unit != null) {
                //创建一个定时线程池,一个任务一个任务执行的场景
                evictor = Executors.newScheduledThreadPool(1, EVICTOR_THREAD_FACTORY);
                task = evictor.scheduleWithFixedDelay(this, this.keepAliveTime, this.keepAliveTime, TimeUnit.NANOSECONDS);
            }
            evictorService = evictor;
            evictorTask = task;
        }

        @Override
        public void run() {
            evictExpiredWorkers();
        }

        ThreadWorker get() {
            if (allWorkers.isDisposed()) {
                return SHUTDOWN_THREAD_WORKER;
            }
            while (!expiringWorkerQueue.isEmpty()) {
                ThreadWorker threadWorker = expiringWorkerQueue.poll();
                if (threadWorker != null) {
                    return threadWorker;
                }
            }

            // No cached worker found, so create a new one.
            ThreadWorker w = new ThreadWorker(threadFactory);
            allWorkers.add(w);
            return w;
        }

        void release(ThreadWorker threadWorker) {
            // Refresh expire time before putting worker back in pool
            threadWorker.setExpirationTime(now() + keepAliveTime);

            expiringWorkerQueue.offer(threadWorker);
        }

        void evictExpiredWorkers() {
            if (!expiringWorkerQueue.isEmpty()) {
                long currentTimestamp = now();

                for (ThreadWorker threadWorker : expiringWorkerQueue) {
                    if (threadWorker.getExpirationTime() <= currentTimestamp) {
                        if (expiringWorkerQueue.remove(threadWorker)) {
                            allWorkers.remove(threadWorker);
                        }
                    } else {
                        // Queue is ordered with the worker that will expire first in the beginning, so when we
                        // find a non-expired worker we can stop evicting.
                        break;
                    }
                }
            }
        }

        long now() {
            return System.nanoTime();
        }

        void shutdown() {
            allWorkers.dispose();
            if (evictorTask != null) {
                evictorTask.cancel(true);
            }
            if (evictorService != null) {
                evictorService.shutdownNow();
            }
        }
    }

当创建io线程后,会把线程放到线程池中执行。

然后回到上面io()方法,看RxJavaPlugins#onIoScheduler方法的执行

    @NonNull
    public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
        //运用 Hook 技术,可以统计IO 线程的使用次数。
        Function f = onIoHandler;
        if (f == null) {
            return defaultScheduler;
        }
        return apply(f, defaultScheduler);
    }
  • Hook 的使用放视
        RxJavaPlugins.setIoSchedulerHandler(new Function() {
            @Override
            public Scheduler apply(Scheduler scheduler) throws Exception {
                Log.d(TAG, "apply: 全局 监听 scheduler:" +scheduler);
                return scheduler;
            }
        });
步骤一流程图

1.2.2、步骤二分析

执行subscribeOn方法,会创建一个ObservableSubscribeOn对象:

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

ObservableSubscribeOn相关代码

public final class ObservableSubscribeOn extends AbstractObservableWithUpstream {
    final Scheduler scheduler;

    public ObservableSubscribeOn(ObservableSource source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }

    @Override
    public void subscribeActual(final Observer s) {
        // s 指下游的 observer
        //创建包囊 SubscribeOnObserver,把 Observer 打包
        final SubscribeOnObserver parent = new SubscribeOnObserver(s);
        //订阅
        s.onSubscribe(parent);
        //步骤三
        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;
            this.s = new AtomicReference();
        }

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

        @Override
        public void onNext(T t) {
            actual.onNext(t);
        }

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

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

        @Override
        public void dispose() {
            DisposableHelper.dispose(s);
            DisposableHelper.dispose(this);
        }

        @Override
        public boolean isDisposed() {
            return DisposableHelper.isDisposed(get());
        }

        void setDisposable(Disposable d) {
            DisposableHelper.setOnce(this, d);
        }
    }

    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver parent;

        SubscribeTask(SubscribeOnObserver parent) {
            this.parent = parent;
        }

        @Override
        public void run() {
            //source 指的是上游的 Obserable
            source.subscribe(parent);
        }
    }
}
  • 步骤一
    SubscribeTaskiObservableSubscribeOn的内部类
    final class SubscribeTask implements Runnable {
      //用 SubscribeOnObserver 打包的 Observer
        private final SubscribeOnObserver parent;
        SubscribeTask(SubscribeOnObserver parent) {
            this.parent = parent;
        }
        @Override
        public void run() {
            //source 指的是上游的 Obserable
            source.subscribe(parent);
        }
    }
  • 步骤二
    执行Scheduler#scheduleDirect方法
    public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
         //等于执行 IoScheduler.createWorker(){new EventLoopWorker(pool.get());} 
        final Worker w = createWorker();  //(1)
        //把 SubscribeTask 包装 Runnable, run 指的是 SubscribeTask
        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); //(2)
        //又包装一层,放入线程池
        DisposeTask task = new DisposeTask(decoratedRun, w);   //(3)
        //执行线程池任务
        w.schedule(task, delay, unit); //(4)
        return task;
    }
  • (1)createWorker() 实际执行的是IoScheduler#createWorker 方法:
    @Override
    public Worker createWorker() {
        return new EventLoopWorker(pool.get());
    }
    
    public int size() {
        return pool.get().allWorkers.size();
    }

    static final class EventLoopWorker extends Scheduler.Worker {
        private final CompositeDisposable tasks;
        private final CachedWorkerPool pool;
        private final ThreadWorker threadWorker;

        final AtomicBoolean once = new AtomicBoolean();

        EventLoopWorker(CachedWorkerPool pool) {
            this.pool = pool;
            this.tasks = new CompositeDisposable();
            this.threadWorker = pool.get();
        }

        @Override
        public void dispose() {
            if (once.compareAndSet(false, true)) {
                tasks.dispose();

                // releasing the pool should be the last action
                pool.release(threadWorker);
            }
        }

        @Override
        public boolean isDisposed() {
            return once.get();
        }

        @NonNull
        @Override
        public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
            if (tasks.isDisposed()) {
                // don't schedule, we are unsubscribed
                return EmptyDisposable.INSTANCE;
            }
            //调度线程池任务
            return threadWorker.scheduleActual(action, delayTime, unit, tasks);
        }
    }
  • (2)调用 RxJavaPlugins#onScheduleSubscribeTask进行包装
    public static Runnable onSchedule(@NonNull Runnable run) {
        ObjectHelper.requireNonNull(run, "run is null");
        // HOOK 节点
        Function f = onScheduleHandler;
        if (f == null) {
            return run;
        }
        //把 SubscribeTask 包装 成 Runnable 返回
        return apply(f, run);
    }
  • (3)Scheduler#DisposeTask对Runnable再次封装成DisposeTask
    static final class DisposeTask implements Disposable, Runnable, SchedulerRunnableIntrospection {
        final Runnable decoratedRun;
        final Worker w;
        Thread runner;

        DisposeTask(Runnable decoratedRun, Worker w) {
            this.decoratedRun = decoratedRun;
            //w 指的是 : 在线程池返回的 IO 任务
            this.w = w;
        }

        @Override
        public void run() {
            runner = Thread.currentThread();
            try {
                decoratedRun.run();
            } finally {
                dispose();
                runner = null;
            }
        }

        @Override
        public void dispose() {
            if (runner == Thread.currentThread() && w instanceof NewThreadWorker) {
                ((NewThreadWorker)w).shutdown();
            } else {
                w.dispose();
            }
        }

        @Override
        public boolean isDisposed() {
            return w.isDisposed();
        }

        @Override
        public Runnable getWrappedRunnable() {
            return this.decoratedRun;
        }
    }
  • (4)执行调度
    Scheduler 里的抽象方法
        public abstract Disposable schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit);

IoScheduler#EventLoopWorker#schedule 执行线程池调度

        public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
            if (tasks.isDisposed()) {
                // don't schedule, we are unsubscribed
                return EmptyDisposable.INSTANCE;
            }

            return threadWorker.scheduleActual(action, delayTime, unit, tasks);
        }

调用NewThreadWorker#scheduleActual 执行线程池任务

    public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
        Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

        ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);

        if (parent != null) {
            if (!parent.add(sr)) {
                return sr;
            }
        }

        Future f;
        try {
            //执行定时线程池任务
            if (delayTime <= 0) {
                f = executor.submit((Callable)sr);
            } else {
                f = executor.schedule((Callable)sr, delayTime, unit);
            }
            sr.setFuture(f);
        } catch (RejectedExecutionException ex) {
            if (parent != null) {
                parent.remove(sr);
            }
            RxJavaPlugins.onError(ex);
        }

        return sr;
    }
 
 

然后回调到Scheduler的内部类DisposeTask,执行里面的 run

    static final class DisposeTask implements Runnable, Disposable {
        final Runnable decoratedRun;
        final Worker w;

        Thread runner;

        DisposeTask(Runnable decoratedRun, Worker w) {
            this.decoratedRun = decoratedRun;
            this.w = w;
        }

        @Override
        public void run() {
            runner = Thread.currentThread();
            try {
                decoratedRun.run();
            } finally {
                dispose();
                runner = null;
            }
        }

        @Override
        public void dispose() {
            if (runner == Thread.currentThread() && w instanceof NewThreadWorker) {
                ((NewThreadWorker)w).shutdown();
            } else {
                w.dispose();
            }
        }

        @Override
        public boolean isDisposed() {
            return w.isDisposed();
        }
    }

最后回调到ObservableSubscribeOn的内部类SubscribeTask,执行里面的 run

    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver parent;

        SubscribeTask(SubscribeOnObserver parent) {
            this.parent = parent;
        }

        @Override
        public void run() {
            //上游传的 Obserable
            source.subscribe(parent);
        }
    }
  • 步骤三
        void setDisposable(Disposable d) {
            DisposableHelper.setOnce(this, d);
        }
    public static boolean setOnce(AtomicReference field, Disposable d) {
        ObjectHelper.requireNonNull(d, "d is null");
        // cas 操作
        if (!field.compareAndSet(null, d)) {
            d.dispose();
            if (field.get() != DISPOSED) {
                reportDisposableSet();
            }
            return false;
        }
        return true;
    }

1.2.3、总结

SubscribeOn整体流程图如下:

SubscribeOn 整体流程图

1.3、ObserveOn

ObserveOn主要用于下游事件切换线程:执行图如下

  • 代码分析
        Observable
                .create(new ObservableOnSubscribe() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter emitter) throws Exception {
                        //io 线程
                        emitter.onNext(11);
                        emitter.onComplete();
                    }
                })
               
                .subscribeOn(Schedulers.io())
                //步骤二
                .subscribeOn(
                        //步骤一
                        AndroidSchedulers.mainThread())
                .subscribe(new Observer() {
                    @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() { }
                });

1.3.1、步骤一

    public static Scheduler mainThread() {
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
    }

调用RxAndroidPlugins#onMainThreadScheduler 里面可以进行HOOK。

    public static Scheduler onMainThreadScheduler(Scheduler scheduler) {
        if (scheduler == null) {
            throw new NullPointerException("scheduler == null");
        }
        //HOOK
        Function f = onMainThreadHandler;
        if (f == null) {
            return scheduler;
        }
        return apply(f, scheduler);
    }

接下来我们看MAIN_THREAD的创建过程

public final class AndroidSchedulers {

    private static final class MainHolder {
        //运用静态内部类的单例模式
        //里面用 Looper.getMainLooper() 创建 Handler ,利用 Handler 进行线程切换
        static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
    }
    //HOOK
    private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
            new Callable() {
                @Override public Scheduler call() throws Exception {
                    return MainHolder.DEFAULT;
                }
            });

    //切换主线程
    public static Scheduler mainThread() {
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
    }

    //自己定义切换的线程类型
    public static Scheduler from(Looper looper) {
        if (looper == null) throw new NullPointerException("looper == null");
        return new HandlerScheduler(new Handler(looper));
    }

    private AndroidSchedulers() {
        throw new AssertionError("No instances.");
    }
}

再看HandlerScheduler里面的代码,怎么处理创建的 Handler

final class HandlerScheduler extends Scheduler {
    //用来进行线程切换,并加入队列中发送
    private final Handler handler;
    HandlerScheduler(Handler handler) {
        //存上面传过来的 Handler 
        this.handler = handler;
    }
    @Override
    public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) {
        if (run == null) throw new NullPointerException("run == null");
        if (unit == null) throw new NullPointerException("unit == null");

        run = RxJavaPlugins.onSchedule(run);
        ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
        handler.postDelayed(scheduled, Math.max(0L, unit.toMillis(delay)));
        return scheduled;
    }

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

    private static final class HandlerWorker extends Worker {
        private final Handler handler;

        private volatile boolean disposed;

        HandlerWorker(Handler handler) {
            this.handler = handler;
        }

        // run 指的是 ObservableObserveOn 的 run任务
        public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
            if (run == null) throw new NullPointerException("run == null");
            if (unit == null) throw new NullPointerException("unit == null");

            if (disposed) {
                return Disposables.disposed();
            }
            //HOOK
            run = RxJavaPlugins.onSchedule(run);
            //把任务 run 打包到 ScheduledRunnable 任务中
            ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
           //把 ScheduledRunnable 打包到 Message 中
            Message message = Message.obtain(handler, scheduled);
            message.obj = this; // Used as token for batch disposal of this worker's runnables.
            //利用Handler发送消息
            handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
            if (disposed) {
                handler.removeCallbacks(scheduled);
                return Disposables.disposed();
            }
            return scheduled;
        }

        @Override
        public void dispose() {
            disposed = true;
            handler.removeCallbacksAndMessages(this /* token */);
        }

        @Override
        public boolean isDisposed() {
            return disposed;
        }
    }

    private static final class ScheduledRunnable implements Runnable, Disposable {
        private final Handler handler;
        private final Runnable delegate;

        private volatile boolean disposed;

        ScheduledRunnable(Handler handler, Runnable delegate) {
            this.handler = handler;
            this.delegate = delegate;
        }

        @Override
        public void run() {
            try {
                delegate.run();
            } catch (Throwable t) {
                IllegalStateException ie =
                    new IllegalStateException("Fatal Exception thrown on Scheduler.", t);
                RxJavaPlugins.onError(ie);
                Thread thread = Thread.currentThread();
                thread.getUncaughtExceptionHandler().uncaughtException(thread, ie);
            }
        }

        @Override
        public void dispose() {
            disposed = true;
            handler.removeCallbacks(this);
        }

        @Override
        public boolean isDisposed() {
            return disposed;
        }
    }
}
步骤一流程图

1.3.2、步骤二

observeOn 执行过程

    public final Observable observeOn(Scheduler scheduler) {
        return observeOn(scheduler, false, bufferSize());
    }

    public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        // scheduler 为用 AndroidSchedulers.mainThread() 创建的 HandlerScheduler
        return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, scheduler, delayError, bufferSize));
    }

创建ObservableObserveOn对象

public final class ObservableObserveOn extends AbstractObservableWithUpstream {
     // scheduler 为用 AndroidSchedulers.mainThread() 创建的 HandlerScheduler
    final Scheduler scheduler;
    final boolean delayError;
    final int bufferSize;
    public ObservableObserveOn(ObservableSource source, Scheduler scheduler, boolean delayError, int bufferSize) {
        super(source);
        this.scheduler = scheduler;
        this.delayError = delayError;
        this.bufferSize = bufferSize;
    }
    //订阅 , observer 为下游的订阅的观察者
    @Override
    protected void subscribeActual(Observer observer) {
        if (scheduler instanceof TrampolineScheduler) {
            // TrampolineScheduler调度器表示在当前事件流的线程执行任务 
            source.subscribe(observer);
        } else {
            //切换线程时执行
            //调用 HandlerScheduler 的 createWorker 创建 HandlerWorker 调度器
            Scheduler.Worker w = scheduler.createWorker();
            //用ObserveOnObserver 给 observer 打包
            source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
        }
    }

    static final class ObserveOnObserver extends BasicIntQueueDisposable
    implements Observer, Runnable {

        private static final long serialVersionUID = 6576896619930983584L;
        //目标观察者
        final Observer actual;
        //调度器(HandlerScheduler)工作线程池
        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;
            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) {
                    @SuppressWarnings("unchecked")
                    QueueDisposable qd = (QueueDisposable) s;

                    int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);

                    if (m == QueueDisposable.SYNC) {
                        sourceMode = m;
                        queue = qd;
                        done = true;
                        //调度
                        actual.onSubscribe(this);
                        schedule();
                        return;
                    }
                    if (m == QueueDisposable.ASYNC) {
                        sourceMode = m;
                        queue = qd;
                        //调度
                        actual.onSubscribe(this);
                        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;
            schedule();
        }

        @Override
        public void onComplete() {
            if (done) {
                return;
            }
            done = true;
            schedule();
        }

        @Override
        public void dispose() {
            if (!cancelled) {
                cancelled = true;
                s.dispose();
                worker.dispose();
                if (getAndIncrement() == 0) {
                    queue.clear();
                }
            }
        }

        @Override
        public boolean isDisposed() {
            return cancelled;
        }

        void schedule() {
            if (getAndIncrement() == 0) {
                 //执行 HandlerWorker 里面的 schedule方法
                 //然后回调当前Run()方法
                // (1)
                worker.schedule(this); 
            }
        }

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

                missed = addAndGet(-missed);
                if (missed == 0) {
                    break;
                }
            }
        }

        void drainFused() {
            int missed = 1;

            for (;;) {
                if (cancelled) {
                    return;
                }

                boolean d = done;
                Throwable ex = error;

                if (!delayError && d && ex != null) {
                    actual.onError(error);
                    worker.dispose();
                    return;
                }

                actual.onNext(null);

                if (d) {
                    ex = error;
                    if (ex != null) {
                        actual.onError(ex);
                    } else {
                        actual.onComplete();
                    }
                    worker.dispose();
                    return;
                }

                missed = addAndGet(-missed);
                if (missed == 0) {
                    break;
                }
            }
        }

        @Override
        public void run() {
            //是否需要丢弃
            if (outputFused) {
                drainFused();
            } else {
                drainNormal();
            }
        }

        boolean checkTerminated(boolean d, boolean empty, Observer a) {
            if (cancelled) {
                queue.clear();
                return true;
            }
            if (d) {
                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;
        }

        @Override
        public int requestFusion(int mode) {
            if ((mode & ASYNC) != 0) {
                outputFused = true;
                return ASYNC;
            }
            return NONE;
        }

        @Nullable
        @Override
        public T poll() throws Exception {
            return queue.poll();
        }

        @Override
        public void clear() {
            queue.clear();
        }

        @Override
        public boolean isEmpty() {
            return queue.isEmpty();
        }
    }
}

我们看(1)的调用过程:
执行Scheduler#schedule方法

        public Disposable schedule(@NonNull Runnable run) {
            return schedule(run, 0L, TimeUnit.NANOSECONDS);
        }

会调到HandlerScheduler的静态内部类HandlerWorker,里面schedule方法

        // run 指的是 ObservableObserveOn 的 run任务
        public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
            if (run == null) throw new NullPointerException("run == null");
            if (unit == null) throw new NullPointerException("unit == null");

            if (disposed) {
                return Disposables.disposed();
            }
            //HOOK
            run = RxJavaPlugins.onSchedule(run);
            //把任务 run 包装到 ScheduledRunnable 任务中
            ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
           //把 ScheduledRunnable 打包到 Message 中
            Message message = Message.obtain(handler, scheduled);
            message.obj = this; // Used as token for batch disposal of this worker's runnables.
            //利用Handler发送消息
            handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
            if (disposed) {
                handler.removeCallbacks(scheduled);
                return Disposables.disposed();
            }
            return scheduled;
        }

1.4、总结

上面的代码终结为下图:


二、背压

Back Pressure经常被翻译为 背压. 是指在异步场景下, 被观察者发送事件速度远快于 观察者处理的速度, 从而导致下游的 buffer溢出, 这种现象叫做背压。
由于观察者与被观察者处于不同线程,所以RxJava内部使用队列来存储事件,Android中默认队列缓存buffersize为16,所以当事件累计超过16个时就会抛出MissingBackpressureException的异常。解决这种问题就需要对被观察者进行流速控制了,而背压正是应对这种问题的一种策略
对于Cold Observable可以采用pull方式来处理背压,但是Hot Observable不适合用pull模型来处理,因为数据会无限的产生,最好采用一些控制策略,比如已经提供的:BufferWindowSampleDebounce操作符。

另外Flowable类是专门用于背压处理的,其它的几个Observable是不支持背压的,但是提供了一些策略可以临时存储一些数据,缓解生产数据量过多问题。

  • onBackpressureDrop:如果消费者无法处理数据,则 onBackpressureDrop 就将observable发送的事件抛弃掉,直到subscriber再次调用request(n)方法的时候,就发送给它这之后的n个事件。
Observable.interval(1, TimeUnit.MILLISECONDS)
    .onBackpressureDrop()
    .observeOn(Schedulers.newThread())
    .subscribe(
        i -> {
            System.out.println(i);
            try {
                Thread.sleep(100);
            } catch (Exception e) { }
        },
        System.out::println);

结果:
0
1
2
...
126
127
12861
12862
...
  • onBackpressurebuffer:nBackpressureBuffer 会缓存所有当前无法消费的数据,直到 Observer 可以处理为止。
Observable.interval(1, TimeUnit.MILLISECONDS)
    .onBackpressureBuffer(1000)
    .observeOn(Schedulers.newThread())
    .subscribe(
        i -> {
            System.out.println(i);
            try {
                Thread.sleep(100);
            } catch (Exception e) { }
        },
        System.out::println
    );

Flowable类
1 使用Observable转换为Flowable,指定背压策略。

Observable.range(1,100)
          .toFlowable(BackpressureStrategy.DROP)

BackpressureStrategy

MISSING:没有任何背压处理策略,如果生产数据过快,可能产生MissingBackpressureException异常,最好

  • Error:在数据生产过快时,抛出MissingBackpressureException异常
  • Latest:当数据生产过快,保留最新生产的数据
  • DROP:当生产数据过快时,最新生产的数据进行丢弃
  • Buffer:buffer所有下游要消费的数据,直到被消费

三、操作符


RxJava提供了几个操作符,在一定程度上也能满足我们的需求。

  • buffer():先将生产的数据放到buffer中,可以指定buffer的大小,这样可以给消费者缓解一些时间来处理生产过快的数据。不过如果数据过多的话,还是会导致资源问题
  • window():告诉Observable把数据进行打包,一次发一批数据给消费者,而不是一个个的发送。消费者采用一些方式可以快速处理一批数据,相比一个个处理不容易出现生产者生产过多的现象。
  • sample():在一段时间内,只发送这段时间里最后一个数据给下游进行处理,throttleFirst()和sample基本相同,在一段时间内,只发送这段时间的第一个数据给下游
  • debouce():在一段时间中,没有新数据产生的话,发送最后产生的那个数据。

你可能感兴趣的:(RxJava(三))