上一篇博客地址:对于RxJava的map操作符的源码解读(推荐先阅读上一篇博客再阅读这一篇)

当我们需要在RxJava的事件流中切换线程来执行代码,也就是使用RxJava的异步事件流编程,我们就需要使用subscribeOn和observeOn来进行切换线程。

那么当我们使用subscribeOn和observeOn来切换线程的时候,源码是怎么做的呢?

subscribeOn

Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {

            }
        })
        .subscribeOn(Schedulers.io())
        .subscribe(new Observer<Object>() {
        	@Override
			public void onSubscribe(Disposable d) {

			}

			@Override
			public void onNext(Object o) {

			}

			@Override
			public void onError(Throwable e) {

			}

			@Override
			public void onComplete() {

			}
		});

这是一段很普通的RxJava代码,我们使用subscribeOn操作符来指定Schedulers里的IO策略,这个策略会创建一个IoScheduler类,这个类内部会封装一个线程池,也就是说我们使用subscribeOn操作符并指定Schedulers的IO策略实质上是使用一个线程池来切换线程,只不过这个线程池的调度RxJava已经帮我们封装好了。

经过上一篇博客,我们已经知道RxJava代码执行是先使用装饰模型封装成一个包裹,然后由这个包裹调用subscribe

对于这段代码而言,我们的第一个包裹是这样的

rxjava 超时判断 rxjava observeon_rx


(source就是我们在create方法中传入的ObservableOnSubscribe对象,这里使用一个简写)当这个包裹执行subscribe方法的时候,源码的逻辑其实是这样的

rxjava 超时判断 rxjava observeon_操作符_02


(executer是一个线程池,SubscribeTask实质上是一个Runnable,其中封装了Observer)当将SubscribeTask这个Runnable提交到线程池之后,就会执行SubscribeTask中的run方法。此时就切换到了一个新线程来执行接下来的代码。

rxjava 超时判断 rxjava observeon_android_03


根据上一篇博客我们知道,最后在source中传入的是包裹2。在这段代码中,包裹2在调用onNext方法进行事件分发的时候,源码的逻辑是这样的

rxjava 超时判断 rxjava observeon_rxjava 超时判断_04


至此,关于这段代码的源码解读结束。接下来是关于observeOn操作符的源码解读。

observeOn

直接上一段代码

Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {

            }
        })
        .observeOn(AndroidSchedulers.mainThread())
		.subscribe(new Observer<Object>() {
			@Override
			public void onSubscribe(Disposable d) {

			}

			@Override
			public void onNext(Object o) {

			}

			@Override
			public void onError(Throwable e) {

			}

			@Override
			public void onComplete() {

			}
		});

不多废话了,直接把整个流程的源码解读都贴出来吧

rxjava 超时判断 rxjava observeon_ide_05


(HandlerScheduler实质上是一个封装了指定主线程的Handler的类,ObserveOnObserver实质上是一个Runnable,其中封装了Observer)

可以看到和上面的subscribeOn操作符的源码流程差不多,只不过使用observeOn操作符切换线程是在onNext事件分发阶段切换的线程。即上图中Observer.onNext是执行在主线程的。

总结

  • 使用subscribeOn操作符会将从某一层的包裹开始切换线程执行;而observeOn操作符会将从某一个onNext开始切换线程。
  • 直接从代码上来说就是subscribeOn操作符会指定该操作符的上一个操作符及其之后的所有语句执行在新的线程(这是之后没有使用observeOn操作符的情况,之后使用了observeOn操作符会切换成新的线程);而observeOn操作符会指定下一个onNext及其之后所有OnNext执行在新的线程。
  • subscribeOn操作符只会以第一个指定的为准;而observeOn操作符可以使用很多次。因为我们通过以上的解读可以知道subscribeOn操作符是从某一层的包裹开始切换线程执行,那么这个线程切换就会以包裹在最里面的那一层ObservableSubscribeOn切换的线程为准;而observeOn操作符是从某一个onNext开始切换线程,因此可以不同的onNext执行在不同的线程。