假设你对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() {@Overridepublic 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>() {@Overridepublic 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中

依据代码和运行结果我总结例如以下:

  1. doOnSubscribe()与onStart()相似,均在代码调用时就会回调。但doOnSubscribe()能够通过subscribeOn()操作符改变运行的线程且越在后面运行越早;
  2. doOnSubscribe()后面紧跟subscribeOn(),那么doOnSubscribe()将于subscribeOn()指定的线程保持一致。假设doOnSubscribe()在subscribeOn()之后,他的运行线程得再看情况分析;
  3. doOnSubscribe()假设在observeOn()后(注意:observeon()后没有紧接着再调用subcribeon()方法)。那么doOnSubscribe的运行线程就是main线程,与observeon()指定的线程没有关系。
  4. 假设在observeOn()之前没有调用过subcribeOn()方法,observeOn()之后subscribe面()方法之前调用subcribeOn()方法,那么他会改变整个代码流程中全部调用doOnSubscribe()方法所在的线程。同一时候也会改变observeOn()方法之前全部操作符所在的线程(有个重要前提:不满足第2点的条件,也就是doOnSubscribe()后面没有调用subscribeOn()方法)。
  5. 假设在observeOn()前后都没有调用过subcribeOn()方法,那么整个代码流程中的doOnSubscribe()运行在main线程,与observeOn()指定的线程无关。同一时候observeOn()之前的操作符也将运行在main线程,observeOn()之后的操作符与observeOn()指定的线程保持一致。

今天就分析到这里,假设有问题请大家反馈交流。

转载于:https://www.cnblogs.com/blfbuaa/p/7383739.html

RxJava中的doOnSubscribe默认运行线程分析相关推荐

  1. JAVA中增强循环中用线程_在Java中以循环方式运行线程

    我是Java中的多线程和同步的新手.我正在尝试实现一项任务,其中给了我5个文件,每个文件将由一个特定线程读取.每个线程应从文件读取一行,然后将执行转发到下一个线程,依此类推.当所有5个线程都读取第一行 ...

  2. 深入Java泛型(四):RxJava中泛型的使用分析

    RxJava出现在我们的视线已经很久了,我自己也有阅读过非常多的文章,谈不上精通,但是勉强称得上会一些简单的使用,近日总是对这种响应式的编程,对RxJava魂牵梦绕,深刻的感觉到自己对泛型的认识,理解 ...

  3. linux中mpich的运行线程,贝叶斯法构建进化树:MrBayes

    1. 简介 使用贝叶斯法构建进化树的软件有很多.在这里简要介绍MrBayes的安装和使用.以下介绍是对几种贝叶斯法构建进化树软件的简介: MrBayes is a program for Bayesi ...

  4. android 不能在子线程中更新ui的讨论和分析

    问题描述 做过android开发基本都遇见过 ViewRootImpl$CalledFromWrongThreadException,上网一查,得到结果基本都是只能在主线程中更改 ui,子线程要修改 ...

  5. python默认参数举例_Python中的默认参数实例分析

    本文研究的主要是Python中的默认参数的相关内容,具体如下. 熟悉C++语言的可以知道,C++语言中的默认参数是写在函数声明中的,为语法糖,与函数的调用无关,是在函数调用的时候由编译器补齐参数然后进 ...

  6. linux下c语言线程传参数,【linux】C语言多线程中运行线程池,在线程池中运行线程池,,传递的结构体参数值为空/NULL/0...

    C语言多线程中运行线程池,在线程池中运行线程池,,传递的结构体参数值为空/NULL/0 本贴问题,之前已经提问过一次,当时已经解决了,原贴在这里https://segmentfault.com/q/1 ...

  7. python 中主线程结束 子线程还在运行么_Python爬虫进阶(二)爬虫之多任务模块(Ⅰ)...

    今天,咱们来讨论多任务模块了. 一.多任务介绍 二.多线程的创建 一.多任务介绍 多任务,有很多场景中的事情是同时进行的,比如开车的时候,手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的.这些就是多 ...

  8. Hhadoop-2.7.0中HDFS写文件源码分析(二):客户端实现(1)

    一.综述 HDFS写文件是整个Hadoop中最为复杂的流程之一,它涉及到HDFS中NameNode.DataNode.DFSClient等众多角色的分工与合作. 首先上一段代码,客户端是如何写文件的: ...

  9. RxJava使用(三)Scheduler 线程控制

    前言 在默认情况下,即在不指定线程的情况下,RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe(),就在哪个线程生产事件:在哪个线程生产事件,就在哪个线程消费事件. 如果需要 ...

最新文章

  1. LC124 Binary Tree Maximum Path Sum
  2. OpenStack 关于admin-openrc.sh的作用(Queens版本)
  3. onresize事件会被多次触发_玩转SpringBoot之通过事件机制参与SpringBoot应用的启动过程...
  4. 互联网人的《三十而已》:裸辞,催婚,职业瓶颈,逃离北上广深......
  5. linux 静态编译 yara
  6. Nginx的SSL相关指令
  7. 2019年的一个小目标,成为csdn的博客专家,纪念一下
  8. 在c语言中large的作用,输入两个数组,调用large函数比较,计数,输出统计结果...
  9. 为什么matlab用不成了,matlab2008 安装了不能用为什么?
  10. 20181027 考试记录
  11. CentOS 7 搭建 L2TP/Ipsec
  12. 轻量级cad绘图工具FoxCAD for mac
  13. Bitvise密钥登录Linux服务器
  14. 字节游戏测试开发面试题
  15. 蜜雪冰城“土”里刨金
  16. 怦然心动(Flipped)-1
  17. android 10.0 SystemUI 状态栏下拉快捷添加截图快捷开关
  18. Linux添加开机自启服务
  19. 使用微信同声传译,实现页面滑动播放
  20. 阿里云视频点播本地调试跨域问题,阿里云视频点播跨域问题

热门文章

  1. 如何检查某个用户是否具有某个权限对象上定义的某种权限
  2. ubuntu20.04LTS系统的终端terminal透明化设置
  3. 截屏当前界面_华为手机居然有这3种神奇的截屏方法,用过后,我就再也离不开了...
  4. 计算机应用基础寒假作业,计算机应用基础理论试卷寒假作业.doc
  5. 一个点是否在矩形内的算法_478,回溯算法解单词搜索
  6. json string 格式_自己动手实现一个简单的JSON解析器
  7. 二叉树展开为链表Python解法
  8. vsflexgrid单元格换行后自动使用行高_Excel表格不会换行?10个超实用Excel小技巧,用了都说好!...
  9. python 初始化数组 numpy,Python Numpy 数组的初始化和基本操作
  10. oracle序列创建及使用,Oracle创建和使用序列