先来一段标准代码分析
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
Log.e(TAG, "上游线程: " + Thread.currentThread().getName());
e.onNext("1111");
}
}).map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return 404;
}
//给上游分配多次,只会在第一次切换
}).subscribeOn(Schedulers.io())
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG, "onSubscribe: " + Thread.currentThread().getName());
}
@Override
public void onNext(Integer s) {
Log.e(TAG, "下游线程: " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
当执行.subscribeOn(Schedulers.io())的时候,这个是切换上游线程的方法
先来看一下Schedulers.io()里面是什么,从字面意思上看肯定是一个io线程,
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
Function<? super Scheduler, ? extends Scheduler> f = onIoHandler;
if (f == null) {
return defaultScheduler;
}
return apply(f, defaultScheduler);
}
上面二个方法返回的是一个Scheduler类,这里暂且不讨论这个类有什么用.我们来看一下onIoScheduler这个方法,首先进来这个onIoHandler一定是空为什么这么确定,我们进来RxJavaPlugins这个类里面看,这里面初始了很多FuncTion但是都没有赋值,所以都为空.所以第一次进来直接Return的是defaultScheduler这个, defaultScheduler这个又是从上面io()方法里面传进了个IO,IO又是什么,
IO位于Schedules这个类里面,是一个static final类,他里面有个静态代码块,所以一进来就为IO初始化了,
static final Scheduler IO;
来看一下Scedulers里面初始化的部分代码,
public final class Schedulers {
static final Scheduler IO;
static {
IO = RxJavaPlugins.initIoScheduler(new Callable<Scheduler>() {
@Override
public Scheduler call() throws Exception {
return IoHolder.DEFAULT;
}
});
}
}
这里我们只关注一下IO这个静态变量,下面这行代码就有点意思,这种写法在ActivityService里面获取一个IBinder也有过,值得借鉴
RxJavaPlugins.initIoScheduler(..)在这个方法时需要传入一个Callable接口,这个接口直接是返回传入的泛型,就如上面代码Callable<Scheduler>传入的是Scheduler返回的也是Scheduler
public interface Callable<V> {
V call() throws Exception;//泛型是什么返回的就是什么,而返回的是交给实现类来实现
}
所以这里我们返回的是一个IoHolder.DEFAULT,也就是直接new IoScheduler(),所以这个IO就是IoHolder
static final class IoHolder {
static final Scheduler DEFAULT = new IoScheduler();
}
public IoScheduler() {
this(WORKER_THREAD_FACTORY);
}
public IoScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
this.pool = new AtomicReference<CachedWorkerPool>(NONE);
start();
}
public void start() {
CachedWorkerPool update = new CachedWorkerPool(KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT, threadFactory);
if (!pool.compareAndSet(NONE, update)) {
update.shutdown();
}
}
最后我们再返回到最开始
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
这个IO我们已经知道了是IoHolder,所以当我们subscribeOn(Schedulers.io())的时候就是subscribeOn(IoHolder),这下我们可以分析subscribeOn这个谅
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
简单,直接是new了一个ObservableSubscribeOn,把当前Observable和传过来的IoHolder当个参数给传进去,到了这里,其实就跟之前map操作符一个样,当我们和下游关联的时候,就会进入到下面这个方法.
public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new Runnable() {
@Override
public void run() {
source.subscribe(parent);
}
}));
}
上面代码可以分析出,我们的上游发射的方法 source.subscribe(parent)是在一个run()里执行,这就如果在subscribe之前不将线程切换到主线程,那么上游和下游都是在IO线程里面操作.
最终会走到ObservableCreate创建操作符的下面这个方法里
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
而这个方法的observer将原始的observer在ObservableSubscribeOn这个被观察者里给替换成了他自己的SubscribeOnObserver
总结
第一步:
先是通过create方法创建了一个ObserableCreate(被观察者)-------->通过map(转换操作符)---->转成被观察者(ObserableMap)----->再通过上游的线程操作符切换成了ObservableSubscribeOn(也是被观察者)----->再通过subscribe这个方法关联上游和下游---->这里会创建一个观察者Observer
第二步
Observable.subscribe这方法里里,由于是了后一个被观察者是ObservableSubscribeOn,所以流程如下
ObservableSubscribeOn.subscribeActual(Observer)---->将传入的observer封装成了自己的SubscribeOnObserver
----->执行Observer.onSubscribe(..)保持这个方法在原有的线程
---->ObserableMap.subscribeActual(subscribeOnObserver)--->将传入的subscribeOnObserver封装成MapObserver
---->ObserableCreate.subscribeActual(mapObserver)
第三步
第二步中最后到的是ObserableCreate.subscribeActual(mapObserver),这个时候是在IO线程中操作的
先是创建一个发射器CreateEmitter
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
然后
mapObserver.onSubscribe(..)--->subscribeOnObserver.onSubscribe(..)------>
在subscribeOnObserver.onSubscribe这个方法会判断是不是已经执行过了这个方法,因为当上游和下游关联的时候,如果走了线程切换会在ObservableSubscribeOn的subscribeActual方法里执行一次,保证关联成功的第一个方法运行在最开始的线程里面.
----->下游的onSubscribe不在这执行
----->ObserableCreate.subscribe(parent) 把创建的发射器传入进来
----->上游的parent.onNext("111111) 在这里就开始发射了一个onNext事件
----->下游开始接收事件mapObserver.onNext("111111)
----->mapObserver会执行Function.apply("111111"),将"111111"转为404
----->subscribeOnObserver.onNext(404)
----->最后就到observer.onNext(404)
如果再执行.observeOn(AndroidSchedulers.mainThread())其实就是多了一个ObservableObserveOn观察者
ObservableSubscribeOn SubscribeOnObserver上游线程切换,他只会影响上游的发射事件线程
ObservableObserveOn ObserveOnObserver下游线程切换,只会影响下游接收事件线程