RxJava2源码学习之一

本篇文章的目的就是分析下面这段代码的执行流程。不究细节。

 Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter emitter) 
            throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();

            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                //订阅
                .subscribe(new Observer() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.e(TAG, "onNext: " + integer);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "onError: " + e.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });

先上个图


RxJava2.png

Observable的create()方法

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

这里首先创建了一个ObservableCreate对象,然后调用RxJavaPlugins.onAssembly()方法。

钩子方法

/**  
 * Calls the associated hook function.
 * @param  the value type
 * @param source the hook's input value
 * @return the value returned by the hook
 */
 public static  Observable onAssembly(@NonNull Observable source) {
      Function f = onObservableAssembly;
      if (f != null) {
          return apply(f, source);
      }
      return source;
}

默认情况下onObservableAssembly = null,RxJavaPlugins.onAssembly()方法只是返回了传入的source

所以Observable的create()方法返回的是一个ObservableCreate对象。

Observable的subscribeOn(Scheduler scheduler)方法

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

忽略钩子方法,所以Observable的subscribeOn()方法返回的是一个ObservableSubscribeOn对象。

Observable的observeOn(Scheduler scheduler)方法

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");
        return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, 
scheduler, delayError, bufferSize));
    }

忽略钩子方法,所以Observable的observeOn()方法返回的是一个ObservableObserveOn对象。

调用subscribe(Observer observer)把被观察者和观察者联系起来。

Observable的subscribe()方法简化版

@Override
public final void subscribe(Observer observer) {     
    //调用关联的钩子方法,可以忽略
    observer = RxJavaPlugins.onSubscribe(this, observer);
    //注释1处,调用subscribeActual()方法
    subscribeActual(observer);
}

注释1处,调用subscribeActual()方法,这是Observable的一个抽象方法。

ObservableObserveOn的subscribeActual()方法简化版

@Override
protected void subscribeActual(Observer observer) {
    //注释1处,创建一个worker
    Scheduler.Worker w = scheduler.createWorker();
    //注释2处,创建一个ObserveOnObserver对象并订阅,对于这个例子来说
    //source就是subscribeOn(Schedulers.io())返回的对象
    source.subscribe(new ObserveOnObserver(observer, w,delayError, bufferSize));
}

注释1处, 使用传入的scheduler创建一个worker对象。我们传入的scheduler是AndroidSchedulers.main(),是一个HandlerScheduler对象。

注释2处,创建一个ObserveOnObserver对象,该对象包装了我们手写的observer对象。然后source订阅ObserveOnObserver对象。这里的source就是subscribeOn()方法返回的Observable对象,这个对象类型是ObservableSubscribeOn。

ObservableSubscribeOn间接继承了Observable类,所以ObservableSubscribeOn的subscribe()方法就是Observable的subscribe()方法。

@Override
public final void subscribe(Observer observer) {     
    //1.调用关联的钩子方法
    observer = RxJavaPlugins.onSubscribe(this, observer);
    //2.调用subscribeActual()方法
    subscribeActual(observer);
}

忽略钩子方法,直接进入ObservableSubscribeOn的subscribeActual()方法。

@Override
public void subscribeActual(final Observer observer) {
    //注释1处,使用下游的observer,构建一个SubscribeOnObserver对象parent 
    final SubscribeOnObserver parent = new SubscribeOnObserver(observer);
    //注释2处,调用observer的onSubscribe()方法
    observer.onSubscribe(parent);
    //注释3处,使用传入的scheduler开始调度任务
    parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}

注释1处,使用传入的observer,构建一个SubscribeOnObserver对象。SubscribeOnObserver是ObservableSubscribeOn的静态内部类。传入的observer是一个ObserveOnObserver对象。

SubscribeOnObserver类部分代码

static final class SubscribeOnObserver extends AtomicReference implements Observer, Disposable {

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

        final AtomicReference upstream;

        SubscribeOnObserver(Observer downstream) {
            this.downstream = downstream;
            //初始化上游
            this.upstream = new AtomicReference();
        }

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

注释2处,调用observer的onSubscribe()方法,这里是没有切换线程的。

ObserveOnObserver的onSubscribe()方法

@Override
public void onSubscribe(Disposable d) {
    //确保downstream.onSubscribe(this);只会调用一次
    if (DisposableHelper.validate(this.upstream, d)) {
         this.upstream = d;
         //...
         queue = new SpscLinkedArrayQueue(bufferSize);
         //这个downstream就是我们手写的observer
         downstream.onSubscribe(this);
    }
}

注释3处,构建了一个SubscribeTask任务,使用传入的scheduler开始调度任务。我们传入的Schedulers.io()是一个IoScheduler对象。我们先不去管调度的细节,但我们可以猜想,这个调度过程就是scheduler内部有一个线程池,可以取出一个线程用来执行我们传入的SubscribeTask对象。

SubscribeTask是ObservableSubscribeOn的内部类。

注意:现在开始切换线程了!!!

当SubscribeTask被调度的时候,会执行run()方法,该方法就是运行在IoScheduler的线程池中的某个线程中的。

final class SubscribeTask implements Runnable {
    private final SubscribeOnObserver parent;

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

    @Override
    public void run() {
        //注释1处,这里的source就是Observable.create()方法返回的对象。
        //source发出数据是在scheduler所调度的线程中完成的。
        source.subscribe(parent);
    }
}

注释1处,这里的source就是Observable.create()方法返回的Observable对象。
在上面的分析中,我们知道Observable的create()方法返回的是一个ObservableCreate对象。当Observable调用subscribe()方法的时候,会进入ObservableCreate的subscribeActual()方法。

@Override
protected void subscribeActual(Observer observer) {
    //注释1处,创建一个CreateEmitter对象
    CreateEmitter parent = new CreateEmitter(observer);
    observer.onSubscribe(parent);

    try {
        //注释2处,订阅观察者
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}

在注释1处,创建一个CreateEmitter对象。CreateEmitter是ObservableCreate的静态内部类。注意CreateEmitter实现了ObservableEmitter接口。

static final class CreateEmitter extends AtomicReference
    implements ObservableEmitter, Disposable {

    final Observer observer;

    CreateEmitter(Observer observer) {
        this.observer = observer;
    }

    @Override
    public void onNext(T t) {
        if (t == null) {
            onError(new NullPointerException("onNext called with null. 
Null values are generally not allowed in 2.x operators and sources."));
            return;
        }
        if (!isDisposed()) {
            observer.onNext(t);
        }
    }

    @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);
            } finally {
                dispose();
            }
            return true;
        }
        return false;
    }

    @Override
    public void onComplete() {
        if (!isDisposed()) {
            try {
                observer.onComplete();
            } finally {
                dispose();
            }
        }
    }
}

在注释2处,source订阅了观察者,这里的source,就是创建ObservableCreate对象的时候传入的ObservableOnSubscribe对象。

Observable.create(new ObservableOnSubscribe() {
    //发射数据
    @Override
    public void subscribe(ObservableEmitter emitter) throws Exception {
        emitter.onNext(1);
        emitter.onNext(2);
        emitter.onNext(3);
        emitter.onComplete();
    }
})

到这里CreateEmitter开始发出数据。调用3次onNext方法,然后调用
onComplete方法。在CreateEmitter对象内部,会真正调用传入的observer(SubscribeOnObserver类型)对应的onNext(T t)方法和onComplete()方法。

  static final class SubscribeOnObserver extends AtomicReference 
  implements Observer, Disposable {

        final Observer downstream;

        final AtomicReference upstream;

        SubscribeOnObserver(Observer downstream) {
            this.downstream = downstream;
            this.upstream = new AtomicReference();
        }

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

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

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

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

    }

SubscribeOnObserver对象的内部分别调用downstream对应的onNext(T t)方法和onComplete()方法。downstream是一个ObserveOnObserver实例。

ObserveOnObserver类精简版

  static final class ObserveOnObserver extends BasicIntQueueDisposable
    implements Observer, Runnable {
    
    //...

    }

ObserveOnObserver的onNext()方法

@Override
    public void onNext(T t) {
        if (done) {
            return;
        }
        //...
        //先把发射出的数据加入队列中
        queue.offer(t);
        schedule();
    }

ObserveOnObserver的schedule()方法

void schedule() {
if (getAndIncrement() == 0) {
   //注释1处
   worker.schedule(this); 
   } 
 }

注释1处的worker对象,就是AndroidSchedulers.mainThread()的createWorker()方法返回的对象。

AndroidSchedulers.mainThread() 就是一个HandlerScheduler对象。

static final Scheduler DEFAULT
            = new HandlerScheduler(new Handler(Looper.getMainLooper()), false);

HandlerScheduler的createWorker()方法。

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

看到了熟悉的Handler和Looper.getMainLooper(),所以由HandlerWorker所调度的线程是运行在主线程的。

注意:开始切换到主线程了!!!

HandlerWorker类精简版

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

    private volatile boolean disposed;

    HandlerWorker(Handler handler, boolean async) {
        this.handler = handler;
        this.async = async;
    }

    @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 (disposed) {
            return Disposables.disposed();
        }
        //ScheduledRunnable是run的装饰者,可以认为就是传入的的run参数
        ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
       //1. 获取message对象
        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);
        }
        //2. 发送消息
        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 Disposables.disposed();
        }

        return scheduled;
    }

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

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

  1. 获取message对象
Message message = Message.obtain(handler, scheduled);

注意一下这个函数

public static Message obtain(Handler h, Runnable callback) {
    Message m = obtain();
    m.target = h;
   //这行代码很重要
    m.callback = callback;

    return m;
}

当message被处理的时候,这个callback对象会执行。

  1. 发送消息,消息发送后,被处理的时候,就会执行我们传入的callback对象的run()方法,别忘了我们传入的run()是一个ObserveOnObserver对象。

ObserveOnObserver的run()方法

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

这两个方法先不去深究,正常应该是走drainNormal方法的。

void drainNormal() {
    int missed = 1;

    final SimpleQueue q = queue;
    //下游的观察者,就是我们手写的observer了
    final Observer 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;
            }
            //观察者的onNext()
            a.onNext(v);
        }

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

在drainNormal()方法中,真正调用了我们手写的observer,而这一切已经是发生在主线程了,舒服,哈哈。

new Observer() {
     @Override
      public void onSubscribe(Disposable d) {
           Log.e(TAG, "onSubscribe: ");
      }

      @Override
      public void onNext(Integer integer) {
            Log.e(TAG, "onNext: " + integer);
      }

      @Override
      public void onError(Throwable e) {
             Log.e(TAG, "onError: " + e.getMessage());
      }

      @Override
       public void onComplete() {
             Log.e(TAG, "onComplete: ");
       }
}

总结:

  1. 为什么subscribeOn(Schedulers.io())可以改变数据源发射数据的线程?

因为Schedulers.io()对应的IoScheduler中维护了一个线程池,数据源发射数据会运行在线程池中的某个线程中。

  1. 为什么observeOn(AndroidSchedulers.mainThread())将数据接收切换到了主线程?

因为AndroidSchedulers.mainThread()对应的HandlerScheduler关联了主线程的Looper。上游发送的数据会通过handler发送Message切换到到主线程。

本篇文章只是分析了一个简单的线程切换的例子,并且很多细节没有关注,在后续的学习和研究过程中会不断完善。

你可能感兴趣的:(RxJava2源码学习之一)