RxJava中的doOnSubscribe默认执行线程分析
来源:互联网 发布:多维分析 数据服务 编辑:程序博客网 时间:2024/06/05 06:26
如果你对RxJava1.x还不是了解,可以参考下面文章。
1. RxJava使用介绍 【视频教程】
2. RxJava操作符
• Creating Observables(Observable的创建操作符) 【视频教程】
• Transforming Observables(Observable的转换操作符) 【视频教程】
• Filtering Observables(Observable的过滤操作符) 【视频教程】
• Combining Observables(Observable的组合操作符) 【视频教程】
• Error Handling Operators(Observable的错误处理操作符) 【视频教程】
• Observable Utility Operators(Observable的辅助性操作符) 【视频教程】
• Conditional and Boolean Operators(Observable的条件和布尔操作符) 【视频教程】
• Mathematical and Aggregate Operators(Observable数学运算及聚合操作符) 【视频教程】
• 其他如observable.toList()、observable.connect()、observable.publish()等等; 【视频教程】
3. RxJava Observer与Subcriber的关系 【视频教程】
4. RxJava线程控制(Scheduler) 【视频教程】
5. RxJava 并发之数据流发射太快如何办(背压(Backpressure)) 【视频教程】
前言
在有心课堂《RxJava之旅》中有学员留言:map和doOnSubscribe默认调度器是IO调度器,这里说错了吧?
下面我们分析下。
在前面讲 Subscriber 的时候,提到过 Subscriber 的 onStart() 可以用作流程开始前的初始化。然而 onStart() 由于在 subscribe() 发生时就被调用了,因此不能指定线程,而是只能执行在 subscribe() 被调用时的线程。这就导致如果 onStart() 中含有对线程有要求的代码(例如在界面上显示一个 ProgressBar,这必须在主线程执行),将会有线程非法的风险,因为有时你无法预测 subscribe() 将会在什么线程执行。
而与 Subscriber.onStart() 相对应的,有一个方法 Observable.doOnSubscribe() 。它和 Subscriber.onStart() 同样是在 subscribe() 调用后而且在事件发送前执行,但区别在于它可以指定线程。
默认情况下, doOnSubscribe() 执行在 subscribe() 发生的线程;而如果在 doOnSubscribe() 之后有 subscribeOn() 的话,它将执行在离它最近的 subscribeOn() 所指定的线程。
示例代码:
Observable.create(onSubscribe) .subscribeOn(Schedulers.io()) .doOnSubscribe(new Action0() { @Override public void call() { progressBar.setVisibility(View.VISIBLE); // 需要在主线程执行 } }) .subscribeOn(AndroidSchedulers.mainThread()) // 指定主线程 .observeOn(AndroidSchedulers.mainThread()) .subscribe(subscriber);
subscribeOn 作用于该操作符之前的 Observable 的创建操符作以及 doOnSubscribe 操作符 ,换句话说就是 doOnSubscribe 以及 Observable 的创建操作符总是被其之后最近的 subscribeOn 控制 。没看懂不要紧,看下面代码你就懂了。
Observable.create(new Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> subscriber) { subscriber.onNext(1); subscriber.onCompleted(); } }) .doOnSubscribe(new Action0() { @Override public void call() { System.out.println("00doOnSubscribe在线程" + Thread.currentThread().getName() + "中"); } }) .subscribeOn(Schedulers.newThread()) .map(new Func1<Integer, String>() { @Override public String call(Integer integer) { System.out.println("map1在线程" + Thread.currentThread().getName() + "中"); return integer + ""; } }) .doOnSubscribe(new Action0() { @Override public void call() { System.out.println("11doOnSubscribe在线程" + Thread.currentThread().getName() + "中"); } }) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .map(new Func1<String, String>() { @Override public String call(String s) { System.out.println("map2在线程" + Thread.currentThread().getName() + "中"); return s + "1"; } }) .doOnSubscribe(new Action0() { @Override public void call() { System.out.println("22doOnSubscribe在线程" + Thread.currentThread().getName() + "中"); } }) .subscribeOn(Schedulers.newThread()) .subscribe(new Subscriber<String>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(String s) { System.out.println("onNext在线程" + Thread.currentThread().getName() + "中"); } });
执行结果如下:
22doOnSubscribe在线程RxNewThreadScheduler-1中11doOnSubscribe在线程RxIoScheduler-3中00doOnSubscribe在线程RxNewThreadScheduler-2中map1在线程RxNewThreadScheduler-2中map2在线程RxIoScheduler-2中onNext在线程RxIoScheduler-2中
根据代码和执行结果我总结如下:
- doOnSubscribe()与onStart()类似,均在代码调用时就会回调,但doOnSubscribe()可以通过subscribeOn()操作符改变运行的线程且越在后面运行越早;
- doOnSubscribe()后面紧跟subscribeOn(),那么doOnSubscribe()将于subscribeOn()指定的线程保持一致;如果doOnSubscribe()在subscribeOn()之后,他的执行线程得再看情况分析;
- doOnSubscribe()如果在observeOn()后(注意:observeon()后没有紧接着再调用subcribeon()方法),那么doOnSubscribe的执行线程就是main线程,与observeon()指定的线程没有关系;
- 如果在observeOn()之前没有调用过subcribeOn()方法,observeOn()之后subscribe面()方法之前调用subcribeOn()方法,那么他会改变整个代码流程中所有调用doOnSubscribe()方法所在的线程,同时也会改变observeOn()方法之前所有操作符所在的线程(有个重要前提:不满足第2点的条件,也就是doOnSubscribe()后面没有调用subscribeOn()方法);
- 如果在observeOn()前后都没有调用过subcribeOn()方法,那么整个代码流程中的doOnSubscribe()执行在main线程,与observeOn()指定的线程无关;同时observeOn()之前的操作符也将执行在main线程,observeOn()之后的操作符与observeOn()指定的线程保持一致。
今天就分析到这里,如果有问题请大家反馈交流。
- RxJava中的doOnSubscribe默认执行线程分析
- Rxandroid中doOnSubscribe()执行默认情况下所在的线程
- Rxjava(其他)--doOnSubscribe原理
- RxJava线程切换源码分析
- Rxandroid中doOnSubscribe(),如何指定其运行的线程?
- RxJava线程切换流程分析_observeOn
- RxJava、RxAndroid中的几个线程控制器
- 默认执行器BlockJUnit4ClassRunner源码分析
- Rxjava中的doOnNext的作用和在哪里执行
- 多线程中的线程等待执行
- 【RxJava Demo分析】(二)Schedulers线程调度器
- 理解RxJava(三)线程调度原理分析
- RxJava分析
- 用一张图解释RxJava中的线程控制
- 用一张图解释RxJava中的线程控制
- Rxjava中的线程控制 —— Scheduler (一)
- 驯服 Tiger: 线程中的默认异常处理
- Handler.post执行时所在线程分析
- 412. Fizz Buzz
- 科研江湖中的一眼清泉之数据简化学会(科普版4k字,附6k字新闻)
- EffectiveJava(16)复合优先于继承
- R语言中报错:invalid argument to unary operator
- DOM、JDOM、DOM4J的区别
- RxJava中的doOnSubscribe默认执行线程分析
- python3的爬虫算法(2)--下载图片并保存到指定途径
- Android ViewPager 实现滑动跟定时循环连播外加底部小红点指示器
- 当时光匆匆才知道梦想遥不可及
- 交换两个数组元素以及求一个整数中二进制位的代码
- javac 编译 & java运行
- android 动画基础
- java中使用jdbcTemplate的query方法举例与总结
- Android Multimedia框架总结(二十六)利用FFmpeg进行解码直播流