android RxJava 消息队列,RxJava2笔记(四、观察者线程切换)

在上一篇文章RxJava2笔记(三、订阅线程切换)中,我们分析了订阅线程是如何切换的,即调用subscribeOn()来切换订阅线程时都执行了哪些操作。在本文我们将继续介绍观察者线程切换,也就是将线程由子线程切换回UI线程。

继续在前面的基础上修改代码,在订阅线程切换方法后调用observeOn(AndroidSchedulers.mainThread())将线程切换回主线程:

Observable.create(new ObservableOnSubscribe() {

@Override

public void subscribe(ObservableEmitter emitter) {

Log.i(TAG, "subscribe--运行线程:" + Thread.currentThread().getName());

emitter.onNext(1);

emitter.onNext(2);

try {

TimeUnit.MILLISECONDS.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

emitter.onNext(3);

emitter.onComplete();

}

})

//将线程由UI线程切换到子线程执行IO请求

.subscribeOn(Schedulers.io())

//将线程切换回UI线程,方面后续操作更新UI界面

.observeOn(AndroidSchedulers.mainThread())

.subscribe(observer);

看下运行结果:

I/MainActivity: onSubscribe--运行线程:main

I/MainActivity: subscribe--运行线程:RxCachedThreadScheduler-1

I/MainActivity: onNext: 1 --运行线程:main

I/MainActivity: onNext: 2 --运行线程:main

I/MainActivity: onNext: 3 --运行线程:main

I/MainActivity: onComplete--运行线程:main

可以看到,subscribe方法运行在子线程中(也就是订阅线程运行在名为RxCachedThreadScheduler-1的一个子线程中,上文提到该线程是由RxJava实现的一个工厂类创建的),而observer运行在名为main的线程中,这个main线程就是UI线程。

看完了输出结果,接下来就看看这个observeOn(AndroidSchedulers.mainThread())是如何将线程切换到UI线程的,点进去看下:

@CheckReturnValue

@SchedulerSupport(SchedulerSupport.CUSTOM)

public final Observable observeOn(Scheduler scheduler) {

//当出现异常时,默认无延迟发送错误。bufferSize()是缓冲区大小,RxJava设置了一个默认大小,为128。

return observeOn(scheduler, false, bufferSize());

}

@CheckReturnValue

@SchedulerSupport(SchedulerSupport.CUSTOM)

public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {

ObjectHelper.requireNonNull(scheduler, "scheduler is null");

ObjectHelper.verifyPositive(bufferSize, "bufferSize");

//包装类,保存上游observable

return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, scheduler, delayError, bufferSize));

}

熟悉的套路,跟调用subscribe.on方法时类似,只是多了一个验证缓冲区大小不为空的代码,这些我们都略过,直接看ObservableObserveOn这个类:

public final class ObservableObserveOn extends AbstractObservableWithUpstream {

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;

}

@Override

protected void subscribeActual(Observer super T> observer) {

//如果传入的调度器是TrampolineScheduler,则不切换线程,在当前线程调度

//但是调度的任务并不是马上执行,而是等待当前任务执行完毕再执行

if (scheduler instanceof TrampolineScheduler) {

source.subscribe(observer);

} else {

//创建工作者worker

Scheduler.Worker w = scheduler.createWorker();

//上游的subscribe,该方法会触发上游的subscribeActual,

//ObserveOnObserver也是一个包装类,保存下游的observer

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

}

}

//......代码省略

}

熟悉的装饰器模式:

1、ObservableObserveOn继承了AbstractObservableWithUpstream,其继承的ObservableSource类型的source成员变量用于保存上游的observable。

2、AndroidSchedulers.mainThread()为本次传入的scheduler,负责将线程切换到UI线程。

3、下游调用subscribe方法是触发=>当前observable的subscribeActual方法=>触发上游observable的subscribe方法=>传入参数包装类ObserveOnObserver(包装了下游的观察者observer)。

这里简要介绍下步骤3:

这里的source是上游的observable对象,source.subscribe()方法实际调用的是上游observable对象的subscribeActual方法,并将下游observer对象的包装类ObserveOnObserver作为参数传递进去,在上游observable对象的subscribeActual方法内,调用ObserveOnObserver包装类中的onSubscribe,onNext等方法,进而调用下游observer的onSubscribe,onNext等方法。

接下来看下ObserveOnObserver这个下游observer包装类:

static final class ObserveOnObserver extends BasicIntQueueDisposable

implements Observer, Runnable {

private static final long serialVersionUID = 6576896619930983584L;

//下游observer

final Observer super T> act

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值