RxJava/RxAndroid源码使用理解

简单了解

  Rx是Reactive Extensions,RxJava就是响应式扩展在Java上的实现。
  它主要通过观察者模式解决了接口回调嵌套阅读复杂的问题,实现链式调用简洁易读的特点。它还实现了适合不同任务的线程,像计算型,IO型,普通型,方便用户选择。
  看一下RxJava一般情况下的使用方式,例子如下:

Observable.create(emit -> {
    
                
            Thread.sleep(5000);
            emit.onNext("1");            
        })
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Object>() {
    
    

                @Override
                public void accept(Object o) throws Throwable {
    
    
                    Log.e("MainActivity", "接收到数据:" + o.toString());
                }
            });

  如上,create里的Lambda表达式,一般情况下,是一个费时操作,不能放到主线程中,这时通过subscribeOn来指定对应线程调度器,这块现在是Schedulers.newThread(),使用普通线程。
   observeOn也是指定线程调度器,这里是AndroidSchedulers.mainThread(),意思是使用主线程处理对应任务。它处理的是哪个任务呢,subscribe订阅的任务。
  下面就根据上面这段代码来分析一下它的原理。

相关类

  先认识一下关键的类,如下:
  Observable:被观察者类,被观察者会继承该类。它在订阅观察者时,会调用subscribe(@NonNull Observer<? super T> observer)方法,不过该方法在Observable类中被声明成final,所以子类不能重写该方法,应该重写subscribeActual(@NonNull Observer<? super T> observer)方法,它会在subscribe()方法中被调用。Observable类里还声明了许多操作符方法。
  Observer:观察者类接口,观察者会继承该类。
  ObservableOnSubscribe:它是一个接口,里面有一个待实现方法subscribe(@NonNull ObservableEmitter emitter)。注意它的参数类型是ObservableEmitter接口类型,它又实现Emitter接口,Emitter接口有三个方法,onNext(@NonNull T value),onError(@NonNull Throwable error),onComplete()。ObservableOnSubscribe对应着上面举例中create()方法里面的Lambda表达式,实现的就是它的subscribe(@NonNull ObservableEmitter emitter)。虽然它没继承Observable,但它应该归为被观察者。
  ObservableCreate:继承Observable,属于被观察者。它是通过Observable.create()方法生成的,在这个例子中,它的成员source是ObservableOnSubscribe对象。
  ObservableSubscribeOn:继承Observable,属于被观察者。在例子中,它是调用subscribeOn()生成的,这里是将ObservableCreate对象和Schedulers.newThread()封装到它的成员变量里面。
  ObservableObserveOn:继承Observable,属于被观察者。例子中,它是调用observeOn()生成的,它的成员变量也包括ObservableSubscribeOn对象,AndroidSchedulers.mainThread()调度器。
  通过上面这几个类对象的链式调用,我们发现后面生成的被观察者对象总是包含前面的被观察者对象,这其实使用的是组合的设计方式。
  LambdaObserver:继承Observer对象,属于观察者。例子中的链式最后一步调用的是subscribe()方法,参数是实现的Consumer接口,其实最终会将Consumer对象封装到LambdaObserver对象中。LambdaObserver对象有4个成员变量,1、Consumer<? super T> onNext,2、Consumer<? super Throwable> onError,3、Action onComplete,4、Consumer<? super Disposable> onSubscribe。其中onNext就是例子中的Consumer接口对象。
  SubscribeOnObserver:继承Observer,是观察者类。它是在ObservableSubscribeOn类中订阅方法subscribeActual()中生成的,它的成员变量downstream也是指向一个观察者对象。
  NewThreadScheduler:普通线程调度器
  HandlerScheduler:Android主线程调度器
  ComputationScheduler:计算型任务调度器
  IoScheduler:IO型任务调度器
  NewThreadWorker:它里面维护了线程池,线程执行都是通过它。
  Scheduler.Worker:它是一层封装,它里面包含着NewThreadWorker或者其子类成员,通过它来传递任务。

代码流程

  按照例子的代码,看一下整个流程
流程图

流程图

  再看一下类结构组合引用图

类结构组合关系图

类结构组合引用关系图

  从上面的图可以看出,每个类对象都包含着它前面的那个对象。
  下面就结合代码来理解一下上面的流程。

1、创建ObservableCreate类对象

    @CheckReturnValue
    @NonNull
    @SchedulerSupport(SchedulerSupport.NONE)
    public static <@NonNull T> Observable<T> create(@NonNull ObservableOnSubscribe<T> source) {
    
    
        Objects.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<>(source));
    }

  可见将ObservableOnSubscribe类对象source设置到新创建ObservableCreate对象的成员变量中。
  它还会调用RxJavaPlugins.onAssembly()函数,

    @NonNull
    public static <@NonNull T> Observable<T> onAssembly(@NonNull Observable<T> source) {
    
    
        Function<? super Observable, ? extends Observable> f = onObservableAssembly;
        if (f != null) {
    
    
            return apply(f, source);
        }
        return source;
    }
    ……
    @NonNull
    static <@NonNull T, @NonNull R> R apply(@NonNull Function<T, R> f, @NonNull T t) {
    
    
        try {
    
    
            return f.apply(t);
        } catch (Throwable ex) {
    
    
            throw ExceptionHelper.wrapOrThrow(ex);
        }
    }

  可见,如果RxJavaPlugins类的静态成员onObservableAssembly被设置过,还会调用它来处理一下前面新生成的ObservableCreate对象。而这里如果设置onObservableAssembly,需要用RxJavaPlugins类的setOnObservableAssembly(),目前我们是没有设置过。RxJavaPlugins类里还设置了好多其他的类似的成员函数,在它这里叫钩子函数。是为了让用户能做一些处理,用户可以实现它。

2、创建ObservableSubscribeOn类对象

  接着需要调用ObservableCreate的subscribeOn(@NonNull Scheduler scheduler),不过它并没有实现该方法,它的实现在Observable类中

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    @NonNull
    public final Observable<T> subscribeOn(@NonNull Scheduler scheduler) {
    
    
        Objects.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<>(this, scheduler));
    }

  可以看到,也是调用了ObservableSubscribeOn的构造函数,这里将ObservableCreate对象和Scheduler对象设置到ObservableSubscribeOn类对象的成员变量中。
  在这个步骤之前,会先创建Scheduler对象,还是拿前面举的例子中的Schedulers.newThread()来说,看它的代码:

扫描二维码关注公众号,回复: 16494980 查看本文章
    @NonNull
    static final Scheduler NEW_THREAD; 
    …………   
    static {
    
    
    …………
        NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new NewThreadTask());
    } 
    …………       
    @NonNull
    public static Scheduler newThread() {
    
    
        return RxJavaPlugins.onNewThreadScheduler(NEW_THREAD);
    }

  可见,在Schedulers类加载的时候,就会创建NEW_THREAD,以后每次调用newThread(),都会返回NEW_THREAD。RxJavaPlugins.onNewThreadScheduler()也是钩子函数,这里没有设置。
  接着看NEW_THREAD 的创建,

    static final class NewThreadTask implements Supplier<Scheduler> {
    
    
        @Override
        public Scheduler get() {
    
    
            return NewThreadHolder.DEFAULT;
        }
    }
    …………
    static final class NewThreadHolder {
    
    
        static final Scheduler DEFAULT = new NewThreadScheduler();
    }    

  NewThreadHolder.DEFAULT是通过NewThreadScheduler类的构造函数来生成对象。
  这样以后再调用Schedulers.newThread()就直接返回NewThreadHolder.DEFAULT对象了。

3、创建ObservableObserveOn类对象

  现在应该调用ObservableSubscribeOn的observeOn()方法,它实现在Observable 类里面:

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

  代码也是和上面类似,生成ObservableObserveOn对象,将ObservableSubscribeOn对象,Scheduler 对象,delayError,bufferSize作为参数封装到ObservableObserveOn对象里面。bufferSize是它里面的实现的单一生产者消费者队列的大小的一个参考值,这里大小为128。
  在这个步骤之前,会先创建Scheduler对象,还是拿前面举的例子中的
  AndroidSchedulers.mainThread()

    private static final class MainHolder {
    
    
        static final Scheduler DEFAULT = internalFrom(Looper.getMainLooper(), true);
    }    
    private static final Scheduler MAIN_THREAD =
        RxAndroidPlugins.initMainThreadScheduler(() -> MainHolder.DEFAULT);
        …………
    public static Scheduler mainThread() {
    
    
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
    }

  该方法得到的也是静态变量MAIN_THREAD,它是通过internalFrom()方法得到的

    @SuppressLint("NewApi") // Checking for an @hide API.
    private static Scheduler internalFrom(Looper looper, boolean async) {
    
    
        // Below code exists in androidx-core as well, but is left here rather than include an
        // entire extra dependency.
        // https://developer.android.com/reference/kotlin/androidx/core/os/MessageCompat?hl=en#setAsynchronous(android.os.Message,%20kotlin.Boolean)
        if (Build.VERSION.SDK_INT < 16) {
    
    
            async = false;
        } else if (async && Build.VERSION.SDK_INT < 22) {
    
    
            // Confirm that the method is available on this API level despite being @hide.
            Message message = Message.obtain();
            try {
    
    
                message.setAsynchronous(true);
            } catch (NoSuchMethodError e) {
    
    
                async = false;
            }
            message.recycle();
        }
        return new HandlerScheduler(new Handler(looper), async);
    }

  这里创建了HandlerScheduler对象,这里面封装了Handler对象,还有async参数,它代表发送的消息Message 是否是异步消息,根据系统版本的不同做了适配。
  这里生成的Handler的looper是Looper.getMainLooper(),代表Handler处理接收到的消息是在主线程处理的。
  这样通过链式层层组合,生成了ObservableObserveOn对象。
  通过第2、3步指定了2个任务调度器。在Android里面耗时的操作一般都是不能放在主线程中执行的,所以第2步的任务调度,是将耗时操作放到新线程中去执行。而耗时结果执行完毕之后,会将执行结果返回给主线程,所以第3步就是切换回主线程中去处理对应结果。
  接着往下看,具体的线程调度,它实现在subscribe()方法中。

4、订阅观察者

  例子中是subscribe了一个Consumer对象,最终它会调用到Observable类文件中如下方法:

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    @NonNull
    public final Disposable subscribe(@NonNull Consumer<? super T> onNext) {
    
    
        return subscribe(onNext, Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION);
    }    
    …………
    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    @NonNull
    public final Disposable subscribe(@NonNull Consumer<? super T> onNext, @NonNull Consumer<? super Throwable> onError,
            @NonNull Action onComplete) {
    
    
        Objects.requireNonNull(onNext, "onNext is null");
        Objects.requireNonNull(onError, "onError is null");
        Objects.requireNonNull(onComplete, "onComplete is null");

        LambdaObserver<T> ls = new LambdaObserver<>(onNext, onError, onComplete, Functions.emptyConsumer());

        subscribe(ls);

        return ls;
    }

  可以看到Consumer对象被封装到LambdaObserver中,并且LambdaObserver对象的成员变量onError设置为Functions.ON_ERROR_MISSING,将onComplete设置为Functions.EMPTY_ACTION,将onSubscribe设置为Functions.emptyConsumer(),接着又调用了subscribe(ls)。

    @SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(@NonNull Observer<? super T> observer) {
    
    
        Objects.requireNonNull(observer, "observer is null");
        try {
    
    
            observer = RxJavaPlugins.onSubscribe(this, observer);

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

  他会调用钩子函数RxJavaPlugins.onSubscribe(),不过这个需要设置,目前是没有设置状态,继续调用subscribeActual(observer),我们知道当前具体实例类型是ObservableObserveOn对象,下面看一下该类的subscribeActual(observer)方法:

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
    
    
        if (scheduler instanceof TrampolineScheduler) {
    
    
            source.subscribe(observer);
        } else {
    
    
            Scheduler.Worker w = scheduler.createWorker();

            source.subscribe(new ObserveOnObserver<>(observer, w, delayError, bufferSize));
        }
    }

  由于当前scheduler不是TrampolineScheduler类型,所以会调用scheduler.createWorker()创建了一个Worker 对象,然后封装到一个ObserveOnObserver对象里面。这例子里,scheduler是HandlerScheduler对象,observer是LambdaObserver对象。source是ObservableSubscribeOn对象,前面也说过,被观察对象的subscribe()方法,最终会调用到ObservableSubscribeOn类的subscribeActual(),看一下它的代码:

    @Override
    public void subscribeActual(final Observer<? super T> observer) {
    
    
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<>(observer);

        observer.onSubscribe(parent);

        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }

  这里先将参数封装到SubscribeOnObserver对象里,然后调用参数的observer.onSubscribe(parent),再将刚才生成的SubscribeOnObserver对象封装到SubscribeTask对象中,接着会调用线程调度器对象的scheduleDirect(),最后将scheduleDirect()生成的对象设置到SubscribeOnObserver对象里。

ObserveOnObserver被订阅

  在这里observer是ObserveOnObserver对象,看一下它的onSubscribe(parent)

        @Override
        public void onSubscribe(Disposable d) {
    
    
            if (DisposableHelper.validate(this.upstream, d)) {
    
    
                this.upstream = d;
                …………
                queue = new SpscLinkedArrayQueue<>(bufferSize);

                downstream.onSubscribe(this);
            }
        }

  这里upstream 是Disposable类引用,刚开始时是null,DisposableHelper.validate(this.upstream, d)是判断upstream为null时,返回true。接着就将this.upstream设置为参数d,d在这里是SubscribeOnObserver对象。其实,如果this.upstream不为null,DisposableHelper.validate()会调用reportDisposableSet()方法,它会抛出异常ProtocolViolationException(“Disposable already set!”),可见一个观察者不能被多次订阅。
  接着生成SpscLinkedArrayQueue对象,它是一个单一生产者单一消费者队列。再调用downstream的onSubscribe(),在这里downstream是LambdaObserver对象,再看一下它的onSubscribe()

LambdaObserver被订阅

    @Override
    public void onSubscribe(Disposable d) {
    
    
        if (DisposableHelper.setOnce(this, d)) {
    
    
            try {
    
    
                onSubscribe.accept(this);
            } catch (Throwable ex) {
    
    
                Exceptions.throwIfFatal(ex);
                d.dispose();
                onError(ex);
            }
        }
    }

  在这里参数是ObserveOnObserver 对象,LambdaObserver 是继承AtomicReference,DisposableHelper.setOnce(this, d)检查它如果没有被设置过,则会将它设置为d,并且返回true。接着会调用onSubscribe.accept(this),这里onSubscribe,通过签名构造LambdaObserver 对象时知,onSubscribe为Functions.emptyConsumer(),它为一个空实现。

调度器调度线程

  返回到ObservableSubscribeOn类的subscribeActual(),执行完ObserveOnObserver的onSubscribe(parent),需要执行scheduler.scheduleDirect()。scheduler是NewThreadScheduler对象。不过scheduleDirect()方法实现在Schduler类中。

    @NonNull
    public Disposable scheduleDirect(@NonNull Runnable run) {
    
    
        return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
    }
    …………
    @NonNull
    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;
    }

  叫Schduler为线程调度器,关键的代码也就是在这里。
  1、调用createWorker()创建一个Worker 对象。
  2、将Runnable 对象decoratedRun和Worker 对象w封装成DisposeTask 对象。
  3、调用Worker 对象的schedule()方法。

创建Worker 对象

  createWorker()在Schduler类中是抽象函数,它的实现在子类中。由于scheduler是NewThreadScheduler对象,看一下它的的实现

    @NonNull
    @Override
    public Worker createWorker() {
    
    
        return new NewThreadWorker(threadFactory);
    }

  threadFactory是一个静态变量,它是线程工厂。创建线程的优先级,如果没有在对应属性中设置,则为Thread.NORM_PRIORITY。可见NewThreadScheduler调度器生成的线程都是普通线程。
  NewThreadWorker对象里面有一个成员变量executor,它是ScheduledExecutorService,实际类型是ScheduledThreadPoolExecutor,一个线程池。

    public static ScheduledExecutorService create(ThreadFactory factory) {
    
    
        final ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1, factory);
        exec.setRemoveOnCancelPolicy(PURGE_ENABLED);
        return exec;
    }
    …………
    …………
    public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory) {
    
    
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue(), threadFactory);
    }

  它的核心线程数是1,最大线程数是Integer.MAX_VALUE,多余的线程完成任务空闲10ms被回收,它的存储队列为DelayedWorkQueue。我们知道DelayedWorkQueue是一个根据延时长短调度任务的线程,并且任务队列大小没有限制,并且核心线程就只有一个,这会导致再多的任务也只会在一个线程中执行。

新线程中调度任务

  看一下NewThreadWorker的schedule()方法

    @NonNull
    @Override
    public Disposable schedule(@NonNull final Runnable action, long delayTime, @NonNull TimeUnit unit) {
    
    
        if (disposed) {
    
    
            return EmptyDisposable.INSTANCE;
        }
        return scheduleActual(action, delayTime, unit, null);
    }
	…………
    @NonNull
    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<Object>)sr);
            } else {
    
    
                f = executor.schedule((Callable<Object>)sr, delayTime, unit);
            }
            sr.setFuture(f);
        } catch (RejectedExecutionException ex) {
    
    
            if (parent != null) {
    
    
                parent.remove(sr);
            }
            RxJavaPlugins.onError(ex);
        }

        return sr;
    }

  参数run现在是SubscribeTask对象,它里面包含SubscribeOnObserver对象。
  首先还是调用RxJavaPlugins.onSchedule(run),来处理一下run,不过这里没有设置相应的方法,所以,还是返回它本身。
  接着将decoratedRun和parent封装到ScheduledRunnable对象中,ScheduledRunnable继承AtomicReferenceArray,实现了Runnable, Callable。它的AtomicReferenceArray的长度为3。0位置放置父容器,就是初始化传进来的parent。1位置放置FUTURE位置,它是线程池执行Callable时返回的对象,2位置放的是线程池运行起来的线程对象。
  再接着,如果参数parent参数不为null,会把生成的ScheduledRunnable对象添加到父容器parent中。
  紧接着就是线程池调度对应的任务,创建新线程执行任务。
  最后调用ScheduledRunnable的setFuture(f)。

创建新线程,调度任务

  前面说了,executor是ScheduledThreadPoolExecutor线程池,在这里会调用它的submit()方法,执行了它之后。会调用sr的call()方法。

    public Object call() {
    
    
        // Being Callable saves an allocation in ThreadPoolExecutor
        run();
        return null;
    }

    @Override
    public void run() {
    
    
        lazySet(THREAD_INDEX, Thread.currentThread());
        try {
    
    
            try {
    
    
                actual.run();
            } catch (Throwable e) {
    
    
                // Exceptions.throwIfFatal(e); nowhere to go
                RxJavaPlugins.onError(e);
                throw e;
            }
        } finally {
    
    
            Object o = get(PARENT_INDEX);
            if (o != PARENT_DISPOSED && compareAndSet(PARENT_INDEX, o, DONE) && o != null) {
    
    
                ((DisposableContainer)o).delete(this);
            }

            for (;;) {
    
    
                o = get(FUTURE_INDEX);
                if (o == SYNC_DISPOSED || o == ASYNC_DISPOSED || compareAndSet(FUTURE_INDEX, o, DONE)) {
    
    
                    break;
                }
            }
            lazySet(THREAD_INDEX, null);
        }
    }

  call()开始执行时,它已经在新线程中了。call()继续调用run(),可以看到ScheduledRunnable的lazySet(THREAD_INDEX, Thread.currentThread()),将THREAD_INDEX设置为它运行的线程对象。
  接着调用actual.run(),这里actual是在ObservableSubscribeOn类的subscribeActual(final Observer<? super T> observer)里生成的SubscribeTask对象。SubscribeTask类是ObservableSubscribeOn的内部类,看一下SubscribeTask类的run()。

@Override
        public void run() {
    
    
            source.subscribe(parent);
        }

  source是来自ObservableSubscribeOn类,在这里是ObservableCreate类对象。parent则是SubscribeOnObserver对象。继续看ObservableCreate类的subscribe(),它会调用subscribeActual()方法:

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
    
    
        CreateEmitter<T> parent = new CreateEmitter<>(observer);
        observer.onSubscribe(parent);

        try {
    
    
            source.subscribe(parent);
        } catch (Throwable ex) {
    
    
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

  可见,把参数SubscribeOnObserver对象封装到CreateEmitter对象里,然后调用SubscribeOnObserver对象的onSubscribe(parent),通知它被订阅了。
  接着继续调用ObservableCreate类对象的成员source.subscribe(parent)。前面也分析过了,source是实现ObservableOnSubscribe接口的对象。它就是我们在例子里Observable.create()的参数里的lambda表达式

Observable.create(emit -> {
    
                
            Thread.sleep(5000);
            emit.onNext("1");            
        })

  看到了吧,现在终于在新线程里执行了我们的耗时操作。最后执行了emit.onNext(“1”),emit目前是CreateEmitter类对象,看一下它的onNext()

        @Override
        public void onNext(T t) {
    
    
            if (t == null) {
    
    
                onError(ExceptionHelper.createNullPointerException("onNext called with a null value."));
                return;
            }
            if (!isDisposed()) {
    
    
                observer.onNext(t);
            }
        }

  在!isDisposed()时,会调用它的成员变量observer.onNext(t),这里observer是SubscribeOnObserver对象。再看一下它的onNext(t):

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

  这里的downstream又是ObserveOnObserver对象。再看一下它的onNext()

        @Override
        public void onNext(T t) {
    
    
            if (done) {
    
    
                return;
            }

            if (sourceMode != QueueDisposable.ASYNC) {
    
    
                queue.offer(t);
            }
            schedule();
        }

  ObserveOnObserver在没有经过设置的情况下,不是异步的。所以将结果存储到queue里,在这里,它是一个单一生产者单一消费者队列。接着就调用ObserveOnObserver类的schedule()

        void schedule() {
    
    
            if (getAndIncrement() == 0) {
    
    
                worker.schedule(this);
            }
        }
HandlerScheduler调度,回到主线程

  在这里它调用它的成员变量worker.schedule(this),不过在调用之前会先将它自身增加1(getAndIncrement()),它的worker是来自ObservableObserveOn类对象的scheduler,在例子中,它是HandlerScheduler。HandlerScheduler通过createWorker()得到HandlerWorker类型的Worker实例。看一下HandlerWorker的schedule()

        @Override
        @SuppressLint("NewApi") // Async will only be true when the API is available to call.
        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 Disposable.disposed();
            }

            run = RxJavaPlugins.onSchedule(run);

            ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);

            Message message = Message.obtain(handler, scheduled);
            message.obj = this; // Used as token for batch disposal of this worker's runnables.

            if (async) {
    
    
                message.setAsynchronous(true);
            }

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

            // Re-check disposed state for removing in case we were racing a call to dispose().
            if (disposed) {
    
    
                handler.removeCallbacks(scheduled);
                return Disposable.disposed();
            }

            return scheduled;
        }

  这块就是Android里面的Handler消息传递了。这里封装了ScheduledRunnable,然后封装成异步消息,发送给主线程去执行,最后主线程去执行ObserveOnObserver类的run()方法。注意一下,这里又产生了线程调度。看一下ObserveOnObserver类的run():

        @Override
        public void run() {
    
    
            if (outputFused) {
    
    
                drainFused();
            } else {
    
    
                drainNormal();
            }
        }

  outputFused是在请求异步处理的时候为true,目前为false。所以会执行drainNormal()。

        void drainNormal() {
    
    
            int missed = 1;

            final SimpleQueue<T> q = queue;
            final Observer<? super T> a = downstream;

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

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

                    try {
    
    
                        v = q.poll();
                    } catch (Throwable ex) {
    
    
                        Exceptions.throwIfFatal(ex);
                        disposed = true;
                        upstream.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;
                }
            }
        }

  我们知道,现在需要处理的结果是在queue里,现在我们就要将这个结果拿到,这里做的就是这个事情。
  checkTerminated(done, q.isEmpty(), a)检查当前ObserveOnObserver的状态,是不是已经执行过dispose(),是不是已经完成。
  如果状态没问题,就会取队列中结果,调用的是v = q.poll(),这样就将前面queue.offer(t)放进去的结果取出来了。如果取出来为null,也认为队列为空。这个时候,也是直接跳出循环。现在不为空,所以就执行a.onNext(v)。这个a是成员变量downstream,它在这里实际是LambdaObserver对象,调用它的onNext()。
  如果我们仔细观察,会发现这块使用了两个无限循环来处理。内循环在执行了LambdaObserver对象的onNext()之后,会再次去取队列中的值,如果为空,则会调出内循环,外面的循环会增加-missed之后,结果为0,再跳出。在前面 ObserveOnObserver类的schedule()的时候,是给它自身增加了1。所以在这加上-1,即为0了。
  再看一下LambdaObserver对象的onNext():

    @Override
    public void onNext(T t) {
    
    
        if (!isDisposed()) {
    
    
            try {
    
    
                onNext.accept(t);
            } catch (Throwable e) {
    
    
                Exceptions.throwIfFatal(e);
                get().dispose();
                onError(e);
            }
        }
    }

  接着就会调用LambdaObserver对象成员onNext的accept()方法。onNext是一个Consumer对象,它就是我们例子中调用subscribe()里面的参数对象,这里的参数t就是我们前面通过CreateEmitter对象的onNext(“1”)方法里的参数结果。这样就实现了在主线程中调用Consumer对象的accept(Object o)方法了。
  捋完这一条完整的数据传递链条,现在应该清楚它的线程调度是怎么回事了吧。它就是通过组合封装的设计模式,实现链式调用,里面主要是线程池创建线程,还有Android的Handler传递消息机制来实现的。

ScheduledRunnable的setFuture(f)

  现在我们要回到前面NewThreadWorker的scheduleActual()方法中,继续看ScheduledRunnable对象的setFuture(f)方法,这里f是线程池执行之后,返回的Future对象。

    public void setFuture(Future<?> f) {
    
    
        for (;;) {
    
    
            Object o = get(FUTURE_INDEX);
            if (o == DONE) {
    
    
                return;
            }
            if (o == SYNC_DISPOSED) {
    
    
                f.cancel(false);
                return;
            }
            if (o == ASYNC_DISPOSED) {
    
    
                f.cancel(true);
                return;
            }
            if (compareAndSet(FUTURE_INDEX, o, f)) {
    
    
                return;
            }
        }
    }

  在这里是启动了一个无限循环,会检查ScheduledRunnable对象在FUTURE_INDEX位置的值,如果为DONE,说明已经执行完毕,直接返回。如果为SYNC_DISPOSED或ASYNC_DISPOSED,这个时候,会调用参数Future对象的cancel()方法,来取消对应任务的执行,之后退出无限循环。如果值和上面的都不同,则会调用compareAndSet(FUTURE_INDEX, o, f),将FUTURE_INDEX位置设置为参数f,然后退出无限循环。
  到这里基本上,把例子里面的逻辑都说通了。
  主要使用了组合的设计方式,不止被观察者是这样,里面的观察者也是如此。都是一步一步先封装好,然后再一步一步拆开。其中里面有线程池的线程调度,Handler的消息机制。

猜你喜欢

转载自blog.csdn.net/q1165328963/article/details/131861999