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

转自:http://www.jianshu.com/p/ecfb9d68d2a2

前言

经过前几篇的介绍,对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 详解
(本文部分内容引用自该博客)


源码地址:https://github.com/43081438/RxJavaSimple/tree/master

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RxJava 切换线程内存泄漏的原因可能有以下几点: 1. 订阅关系未正确取消:在使用RxJava进行线程切换时,如果没有正确取消订阅关系,就可能导致内存泄漏。因为订阅关系会持有被观察者和观察者之间的引用,如果未及时取消订阅,就会导致观察者无法被释放,从而造成内存泄漏。 2. 使用错误的调度器:在RxJava中,切换线程需要使用Scheduler来指定要切换到的线程。如果使用了错误的调度器,可能导致线程资源无法正确释放,从而造成内存泄漏。 3. 长时间运行的任务:如果在使用RxJava进行线程切换时,执行的任务是一个长时间运行的任务,可能会导致内存泄漏。因为长时间运行的任务可能会持有一些资源,如果没有及时释放这些资源,就会造成内存泄漏。 为避免RxJava切换线程内存泄漏,可以采取以下几个措施: 1. 及时取消订阅关系:在不需要继续观察的时候,及时取消订阅关系,可以使用CompositeDisposable来管理多个订阅关系,确保在不需要时能够正确取消订阅。 2. 使用正确的调度器:在进行线程切换时,确保使用正确的调度器,比如使用Schedulers.io()进行IO操作,使用AndroidSchedulers.mainThread()进行主线程操作。 3. 避免长时间运行的任务:如果任务可能会持续较长时间,可以考虑使用takeUntil等操作符来限制任务的执行时间。 通过以上措施,可以有效避免RxJava切换线程内存泄漏的问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值