关于RxJava的简单用法(三)

本文详细介绍了RxJava中的线程控制机制,包括Scheduler的作用、常见Scheduler类型及其用途,并通过实例说明subscribeOn与observeOn的区别及应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程控制 —— Scheduler

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:线程控制器,可以指定每一段代码在什么样的线程中执行。

调度器类型

 用途
Schedulers.computation( )用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量.
计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
Schedulers.from(executor)使用指定的Executor作为调度器
Schedulers.immediate( )在当前线程立即开始执行任务;
直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
Schedulers.io( )用于IO密集型任务,如异步阻塞IO操作,这个调度器的线程池会根据需要增长;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io( )默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器;
I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
Schedulers.newThread( )为每个任务创建一个新线程
Schedulers.trampoline( )当其它排队的任务完成后,在当前线程排队开始执行
AndroidSchedulers.mainThread()此调度器为RxAndroid特有,顾名思义,运行在Android UI线
还有两个方法必须知道:
  • subscribeOn():指定subscribe() 所发生的线程,即 Observable.OnSubscribe 被激活时所处的线程。或者叫做事件产生的线程。如果出现了多次,只会执行第一个.其他的无效.影响前后部分方法执行在什么线程中.

Observable.just("3")//在子线程中运行
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        //在主线程中运行
                       Log.d("Action0",Thread.currentThread().getName()+"0");
                    }
                })
                .subscribeOn(AndroidSchedulers.mainThread()) // 指定主线程
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d("Action0",Thread.currentThread().getName()+"1");
                    }
                });

这个例子比较特殊,subscribeOn有效执行了两次.因为它要指定doOnSubscribe的工作线程;并且doOnSubscribe执行在它后面代码所指定的线程;

  • observeOn():指定Subscriber 所运行在的线程。或者叫做事件消费的线程。可以多次指定线程;影响他后面的代码执行在什么线程内;

Observable.create(new Observable.OnSubscribe<Data>() {
    @Override
    public void call(Subscriber<? super Data> subscriber) {
        Data data = getData();//从数据库获取
        subscriber.onNext(data);
        subscriber.onCompleted();
    }})
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<Data>() {
            @Override
            public void call(Data data) {

                    //更新ui
            }
        });

简单粗暴的解释一下,subscribeOn( )决定了发射数据在哪个调度器上执行,observeOn(AndroidSchedulers.mainThread())则指定数据接收发生在UI线程。

 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线程中执行。

由这两位大神文章合并成本文章

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

http://www.jianshu.com/p/5c221c58e141

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值