【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>() {
                    @Override
                    public String call(Student i) {
                        String name = i.getName();//获取Student对象中的name
                        return name;//返回name
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public 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>() {
                    @Override
                    public 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>() {
                    @Override
                    public String call(String s) {
                        return handleString(s);       //处理数据
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())//指定:在主线程中处理
                .subscribe(new Action1<String>() {
                    @Override
                    public 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 详解 (本文部分内容引用自该博客)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏YouMeek

优化单点登录流程的好东西:JWT 介绍

JWT 概念 官网介绍:https://jwt.io/introduction/ 别人翻译(翻译得很好):https://github.com/smilings...

1.4K8
来自专栏流媒体

Https详解+wireshark抓包演示

在说HTTPS之前先说说什么是HTTP,HTTP就是我们平时浏览网页时候使用的一种协议。HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传...

4335
来自专栏JadePeng的技术博客

易企秀H5 json配置文件解密分析

最近需要参考下易企秀H5的json配置文件,发现已经做了加密,其实前端的加密分析起来只是麻烦点。

1233
来自专栏何俊林

RxJava 在Android中的应用

RxJava 是什么, 能解决什么问题 对比其他技术理解为什么要选择RxJava RxJava的相关API RxJava在Android中的典型使用场景 RxJ...

2487
来自专栏PHP在线

apache开启openssl支持

一、 加载 Apache SSL 模块 如果已经安装过 apache2.2 ,现在需要额外添加 SSL 支持,那么你需要重新编译安装一次 apache2。 编...

4047
来自专栏阮一峰的网络日志

JSON Web Token 入门教程

JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理和用法。

2015
来自专栏运维

Nginx反向代理负载均衡配置梳理大全

利用ngx_http_core_module、ngx_http_rewrite_module模块 主要是301跳转 Return写法:域名http请求跳转到对应...

1221
来自专栏IMWeb前端团队

Nodejs进阶:核心模块https 之 如何优雅的访问12306

本文作者:IMWeb 陈映平 原文出处:IMWeb社区 未经同意,禁止转载 模块概览 这个模块的重要性,基本不用强调了。在网络安全问题日益严峻的今天,...

28710
来自专栏刘望舒

Android响应式编程(一)RxJava前篇[入门基础]

1.RxJava概述 ReactiveX与RxJava 在讲到RxJava之前我们首先要了解什么是ReactiveX,因为RxJava是ReactiveX的一种...

2205
来自专栏Web 开发

申请SSL开启SPDY服务

12月10日的时候,整个站点就已经装上了Nginx 1.4,配置文件里面已经可以开启SPDY功能,不过那时候一直缺少一枚SSL证书。

790

扫码关注云+社区