【Android】RxJava的使用(四)线程控制 —— Scheduler

并没有关系的图

前言

经过前几篇的介绍,对RxJava对模式有了一定的理解:由Observable发起事件,经过中间的处理后由Observer消费。(对RxJava还不了解的可以出门左拐)
之前的代码中,事件的发起和消费都是在同一个线程中执行,也就是说之前我们使用的RxJava是同步的~~~
观察者模式本身的目的不就是后台处理,将处理结果回调给前台?这同步的是要哪样?所以,这篇为大家介绍RxJava的重要的概念——Scheduler

参考:给 Android 开发者的 RxJava 详解
(本文部分内容引用自该博客)

介绍

RxJava在不指定线程的情况下,发起时间和消费时间默认使用当前线程。所以之前的做法

        Observable.just(student1, student2, student2)//使用map进行转换,参数1:转换前的类型,参数2:转换后的类型.map(new Func1<Student, String>() {@Overridepublic String call(Student i) {String name = i.getName();//获取Student对象中的namereturn name;//返回name}}).subscribe(new Action1<String>() {@Overridepublic void call(String s) {nameList.add(s);}});

因为是在主线程中发起的,所以不管中间map的处理还是Action1的执行都是在主线程中进行的。若是map中有耗时的操作,这样会导致主线程拥塞,这并不是我们想看到的。

Scheduler

Scheduler:线程控制器,可以指定每一段代码在什么样的线程中执行。
模拟一个需求:新的线程发起事件,在主线程中消费

    private void rxJavaTest3() {Observable.just("Hello", "Word").subscribeOn(Schedulers.newThread())//指定 subscribe() 发生在新的线程.observeOn(AndroidSchedulers.mainThread())// 指定 Subscriber 的回调发生在主线程.subscribe(new Action1<String>() {@Overridepublic void call(String s) {Log.i(TAG, s);}});

上面用到了subscribeOn(),和observeOn()方法来指定发生的线程和消费的线程。

  • subscribeOn():指定subscribe() 所发生的线程,即 Observable.OnSubscribe 被激活时所处的线程。或者叫做事件产生的线程。
  • observeOn():指定Subscriber 所运行在的线程。或者叫做事件消费的线程。

以及参数Scheduler,RxJava已经为我们提供了一下几个Scheduler

  • Schedulers.immediate():直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
  • Schedulers.newThread():总是启用新线程,并在新线程执行操作。
  • Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
  • Schedulers.computation():计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
  •  AndroidSchedulers.mainThread():它指定的操作将在 Android 主线程运行。

多次切换线程

看完上面的介绍想必对RxJava线程的切换有了一些理解,上面只是对事件的发起和消费制定了线程。如果中间有map之类的操作呢?是否可以实现发起的线程在新线程中,map的处理在IO线程,最后的消费在主线程中。

        Observable.just("Hello", "Wrold").subscribeOn(Schedulers.newThread())//指定:在新的线程中发起.observeOn(Schedulers.io())         //指定:在io线程中处理.map(new Func1<String, String>() {@Overridepublic String call(String s) {return handleString(s);       //处理数据}}).observeOn(AndroidSchedulers.mainThread())//指定:在主线程中处理.subscribe(new Action1<String>() {@Overridepublic void call(String s) {show(s);                       //消费事件}});

可以看到observeOn()被调用了两次,分别指定了map的处理的现场和消费事件show(s)的线程。

若将observeOn(AndroidSchedulers.mainThread())去掉会怎么样?不为消费事件show(s)指定线程后,show(s)会在那里执行?
其实,observeOn() 指定的是它之后的操作所在的线程。也就是说,map的处理和最后的消费事件show(s)都会在io线程中执行。
observeOn()可以多次使用,可以随意变换线程

小结

学会线程控制后才算是真正学会了使用RxJava。RxJava的使用十分灵活,想要对其熟悉使用只有一个办法,那就是多用啦,熟能生巧。

以上有错误之处感谢指出

参考:给 Android 开发者的 RxJava 详解
(本文部分内容引用自该博客)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sed: -e expression #1, unknown option to `s'解决办法

报错如下&#xff1a; sed: -e expression #1, char 13: unknown option to s 需要替换的行为&#xff1a; monitor.urlhttp://192.168.25.100:8443/rest 查询资料得知&#xff0c;报错是因为替换的字符串包含有分隔符/ 所以这行改一下分隔符就可以解决问题了 改成感叹号!或者|…

Linux常用开发环境软件-Redis安装(docker环境下)

linux&#xff0c;docker安装RabbitMQ版本 1、从docker官网仓库下载安装RabbitMQ镜像 官网地址&#xff1a;https://hub.docker.com/ docker pull redis:4.0.8  //后面是版本,Tag Name 2、启动Docker Redis镜像 docker run -d -p 6379:6379 redis:4.0.8  启动镜像&#xff…

以当天日期时间,打包目录

#备份/data目录#!/bin/bash DATEdate %Y-%m-%d-%H:%M:%S tar cvf /mnt/resource/script/prod_master_data.$DATE.tar.gz /data[root111 script]# ll total 2536 -rw-r--r-- 1 root root 2590720 Feb 22 21:46 prod_master_data.2019-02-22-21:46:53.tar.gz转载于:https://blog.…

lvs+keepalived详解

常用软件安装及使用目录 资源链接&#xff1a;https://pan.baidu.com/s/15rFjO-EnTOyiTM7YRkbxuA 网盘分享的文件在此 官网&#xff1a;http://www.linuxvirtualserver.org/index.html 中文资料 LVS项目介绍 http://www.linuxvirtualserver.org/zh/lvs1.html …

微信自动打卡

要有第二台安卓 手机&#xff0c;打开usb、adb调试&#xff0c;永不锁屏&#xff0c;永不休眠&#xff0c;手机安装了微信并至少成功登陆过一次&#xff0c; 一台不关机的电脑&#xff0c;手机连接电脑&#xff0c;Appium服务器保持启动&#xff0c;在开始菜单 设定好任务计划程…

利用反射做类参数的校验

需求描述 业务需求描述&#xff1a;对webservice接口参数校验 代码实现 /*** 字符串长度校验* * param str* param len* return 合法(true),不合法(false)*/public static boolean check(String str, int len) {if (null ! str && str.length() > len) {return fals…

跨域的四种方式

本文主要是关于跨域的几种方式&#xff0c;关于什么是跨域这里就不多说了&#xff0c;写这个也是为了记住一些知识点的。 一. jsonp jsonp的跨域方式很容易理解&#xff0c;页面的的每一个script标签浏览器都会发送get请求获取对应的文本资源&#xff0c;获取到了之后&#xff…

Linux之read命令使用

ead命令&#xff1a; read 命令从标准输入中读取一行&#xff0c;并把输入行的每个字段的值指定给 shell 变量 1&#xff09;read后面的变量var可以只有一个&#xff0c;也可以有多个&#xff0c;这时如果输入多个数据&#xff0c;则第一个数据给第一个变量&#xff0c;第二个数…

python之路day10-命名空间和作用域、函数嵌套,作用域链、闭包

楔子 假如有一个函数&#xff0c;实现返回两个数中的较大值&#xff1a; def my_max(x,y):m x if x>y else yreturn mbigger my_max(10,20)print(bigger) 之前是不是我告诉你们要把结果return回来你们就照做了&#xff1f;可是你们有没有想过&#xff0c;我们为什么要把结…

hive(II)--sql考查的高频问题

在了解别人hive能力水平的时候&#xff0c;不管是别人问我还是我了解别人&#xff0c;有一些都是必然会问的东西。问的问题也大都大同小异。这里总结一下我遇到的那些hive方面面试可能涉及的问题 1、行转列&#xff08;列转行&#xff09; 当我们建设数据仓库时&#xff0c;我们…

java概述

一、java平台无关&#xff1a;jvm二、java健壮语言&#xff1a;无指针&#xff0c;语法上无指正&#xff0c;无内存申请与释放。 三、java核心机制而&#xff1a; jvmjava垃圾收集机制 GC四、java运行过程&#xff1a;源程序&#xff08;.java&#xff09;——》java编译器——…

时间间隔

计算当前时间与上次执行时间的时间间隔。 NSTimeInterval timetravel [[NSDate date]timeIntervalSinceDate:self.lastPlaySoundDate];if (timetravel<3.0) {DLog("时间太短&#xff0c;。。");}self.lastPlaySoundDate [NSDate date]; 转载于:https://www.cnb…

.Net+MySQL组合开发(二) 数据访问篇

一、建立数据库、表、添加数据这里我们使用图形化操作的SQL Manager 2005 Lite for MySQL来建立数据&#xff0c;它的操作界面非常类似OFFICE软件&#xff0c;使用方便、很容量上手、下面开始建立数据库及表单击"Creat New DataBase"&#xff1a;新建DB输入密码&…

Git vs SVN

一、Git vs SVN Git 和 SVN 孰优孰好&#xff0c;每个人有不同的体验。Git是分布式的&#xff0c;SVN是集中式的这是 Git 和 SVN 最大的区别。若能掌握这个概念&#xff0c;两者区别基本搞懂大半。因为 Git 是分布式的&#xff0c;所以 Git 支持离线工作&#xff0c;在本地可以…

.net api 和java平台对接技术总结

这两天 一直和京东对接接口&#xff0c;我们用.net api 提供接口&#xff0c;对方用java调用&#xff0c;本来没什么问题&#xff0c;但是对方对数据安全要求特别严&#xff0c;要验签&#xff0c;于是噩梦开始了。 1、在传输的时候&#xff0c;约定传输格式&#xff1a; HttpW…

Burpsuite学习(4)

2019独角兽企业重金招聘Python工程师标准>>> burpsuite spider模块通过跟踪 HTML 和 JavaScript 以及提交的表单中的超链接来映射目标应用程序&#xff0c;它还使用了一些其他的线索&#xff0c;如目录列表&#xff0c;资源类型的注释&#xff0c;以及 robots.txt 文…

Git删除分支/恢复分支

这是https://www.cnblogs.com/utank/p/7880441.html的方法&#xff0c;虽然很老现在有点不一样&#xff0c;但总体还是能用的。 总结就是两种方法 1.用commit的id恢复 2.用reflog的头指针恢复 •删除一个已被终止的分支 如果需要删除的分支不是当前正在打开的分支&#xff0c;使…

NetCore2.0Web应用之Startup

为什么80%的码农都做不了架构师&#xff1f;>>> 作为main函数的程序启动文件UseStartup 默认就是调用我们的整个应用程序的启动文件 class Program{static void Main(string[] args){var host new WebHostBuilder().UseKestrel() // 指定WebServer为Kes…

windows XP系统下oracle完整卸载过程

NT环境下&#xff1a; 1、以NT的Administrator 登陆 2、通过控制面版-〉服务&#xff0c;停掉所有ORACLE服务 3、打开注册表&#xff08;REGEDIT命令&#xff09;&#xff0c;删除HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE 4、打开注册表中的 HKEY_LOCAL_MACHINE\SYSTEM\CurrentCont…

Hadoop----hdfs的基本操作

2019独角兽企业重金招聘Python工程师标准>>> HDFS操作文件的基本命令 1.创建文件夹 $>hdfs dfs -mkdir /user/centos/hadoop 2.展示目录 $>hdfs dfs -ls -r /user/centos/hadoop 3.递归展示 $>hdfs dfs -lsr /user/centos/hadoop 4.上传文件 $&g…