RxJava笔记2:线程控制

基本概念

默认情况下,上游和下游都在创建时所在的线程中工作,比如在Activity中创建的,那它们就在主线程中。Android中不能在主线程执行耗时操作,不然会造成应用的卡顿或发生ANR。比如上游需要从服务器请求数据,或者从数据库查询大量数据,完成后发布结果事件,下游根据接受的事件来显示界面,这时就需要控制上游和下游的线程了。

subscribeOn用于指定上游的线程;

public final Observable<T> subscribeOn(Scheduler scheduler)

observeOn用于指定下游的线程;

public final Observable<T> observeOn(Scheduler scheduler)

两个方法都接受调度器 Scheduler 参数,Scheduler 提供了不同的线程:
Schedulers. io() 代表io操作的线程
Schedulers.computation() 代表CPU计算密集型的操作
Schedulers.newThread() 代表一个常规的新线程
AndroidSchedulers.mainThread() 代表Android的主线程

如果只指定上游线程,不指定下游线程,下游线程和上游线程一样。

//Activity的onCreate方法
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Observable.create(new ObservableOnSubscribe<Object>() {
        @Override
        public void subscribe(ObservableEmitter<Object> e) throws Exception {
            System.out.println("emit 1 thread " + Thread.currentThread().getName());
            e.onNext(1);
            e.onComplete();
        }
    }).subscribeOn(Schedulers.io())
            .subscribe(new Observer<Object>() {
                @Override
                public void onSubscribe(Disposable d) {
                    System.out.println("A onSubscribe thread " + Thread.currentThread().getName());
                }
                @Override
                public void onNext(Object o) {
                    System.out.println("A onNext o " + o + " thread " + Thread.currentThread().getName());
                }
                @Override
                public void onError(Throwable e) {
                    System.out.println("A onError" + e + " thread " + Thread.currentThread().getName());
                }
                @Override
                public void onComplete() {
                    System.out.println("A onComplete thread " + Thread.currentThread().getName());
                }
            });
}
//打印结果
System.out: A onSubscribe thread main
System.out: emit 1 thread RxCachedThreadScheduler-1
System.out: A onNext o 1 thread RxCachedThreadScheduler-1//与上游线程相同
System.out: A onComplete thread RxCachedThreadScheduler-1

如果只指定下游线程,不指定上游线程,上游线程为当前线程。

//Activity的onCreate方法
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Observable.create(new ObservableOnSubscribe<Object>() {
        @Override
        public void subscribe(ObservableEmitter<Object> e) throws Exception {
            System.out.println("emit 1 thread " + Thread.currentThread().getName());
            e.onNext(1);
            e.onComplete();
        }
    }).observeOn(Schedulers.io())
            .subscribe(new Observer<Object>() {
                @Override
                public void onSubscribe(Disposable d) {
                    System.out.println("A onSubscribe thread " + Thread.currentThread().getName());
                }
                @Override
                public void onNext(Object o) {
                    System.out.println("A onNext o " + o + " thread " + Thread.currentThread().getName());
                }
                @Override
                public void onError(Throwable e) {
                    System.out.println("A onError" + e + " thread " + Thread.currentThread().getName());
                }
                @Override
                public void onComplete() {
                    System.out.println("A onComplete thread " + Thread.currentThread().getName());
                }
            });
}
//打印结果
System.out: A onSubscribe thread main
System.out: emit 1 thread main  //上游线程为当前主线程
System.out: A onNext o 1 thread RxCachedThreadScheduler-1
System.out: A onComplete thread RxCachedThreadScheduler-1

从上面测试结果可以发现,无论上游和下游指定什么线程,onSubscribe方法的线程始终是执行订阅操作所在的主线程,也就是我们虽然可以指定上游下游的线程,但是却无法指定onSubscribe方法的线程。假如订阅操作不是在主线程,我需要在 onSubscribe 时通知界面,就会很难受。所幸,RxJava 提供了doOnSubsricbe 方法,该方法也是在订阅时调用(如果上游下游同一线程onSubscribe 比onSubscribe 调用早,否则不是),并且我们可以指定它的执行线程,通过subscribeOn来指定

//Activity的onCreate方法
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Observable.create(new ObservableOnSubscribe<Object>() {
        @Override
        public void subscribe(ObservableEmitter<Object> e) throws Exception {
            System.out.println("emit 1 thread " + Thread.currentThread().getName());
            e.onNext(1);
            e.onComplete();
        }
    }).doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            System.out.println("doOnSubscribe thread " + Thread.currentThread().getName());
        }
    }).subscribeOn(Schedulers.newThread())
            .observeOn(Schedulers.newThread())
            .subscribe(new Observer<Object>() {
                @Override
                public void onSubscribe(Disposable d) {
                    System.out.println("A onSubscribe thread " + Thread.currentThread().getName());
                }
                @Override
                public void onNext(Object o) {
                    System.out.println("A onNext o " + o + " thread " + Thread.currentThread().getName());
                }
                @Override
                public void onError(Throwable e) {
                    System.out.println("A onError" + e + " thread " + Thread.currentThread().getName());
                }
                @Override
                public void onComplete() {
                    System.out.println("A onComplete thread " + Thread.currentThread().getName());
                }
            });
}
//打印结果
System.out: A onSubscribe thread main
System.out: doOnSubscribe thread RxNewThreadScheduler-1//doOnSubscribe 在指定的线程中
System.out: emit 1 thread RxNewThreadScheduler-1
System.out: A onNext o 1 thread RxNewThreadScheduler-2
System.out: A onComplete thread RxNewThreadScheduler-2

subscribeOn作用范围是从它开始往上,如果多次调用subscribeOn,上游的线程为从下往上,离它最近的那个subscribeOn指定的线程

Observable.create(new ObservableOnSubscribe<Object>() {
    @Override
    public void subscribe(ObservableEmitter<Object> e) throws Exception {
        System.out.println("emit 1 thread " + Thread.currentThread().getName());
        e.onNext(1);
        e.onComplete();
    }
}).subscribeOn(Schedulers.newThread())// subscribeOn 1
        .doOnSubscribe(new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) throws Exception {
                System.out.println("doOnSubscribe thread " + Thread.currentThread().getName());
            }
        })
        .doOnNext(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {
                System.out.println("doOnNext o " + o + " thread " + Thread.currentThread().getName());
            }
        })
        .subscribeOn(Schedulers.newThread())// subscribeOn 2
        .subscribeOn(AndroidSchedulers.mainThread())// subscribeOn 3
        .observeOn(Schedulers.newThread())
        .subscribe(new Observer<Object>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("A onSubscribe thread " + Thread.currentThread().getName());
            }
            @Override
            public void onNext(Object o) {
                System.out.println("A onNext o " + o + " thread " + Thread.currentThread().getName());
            }
            @Override
            public void onError(Throwable e) {
                System.out.println("A onError" + e + " thread " + Thread.currentThread().getName());
            }
            @Override
            public void onComplete() {
                System.out.println("A onComplete thread " + Thread.currentThread().getName());
            }
        });
//打印结果
System.out: A onSubscribe thread main
System.out: doOnSubscribe thread RxNewThreadScheduler-1
System.out: emit 1 thread RxNewThreadScheduler-2
System.out: doOnNext o 1 thread RxNewThreadScheduler-2
System.out: A onNext o 1 thread RxNewThreadScheduler-3
System.out: A onComplete thread RxNewThreadScheduler-3

subscribeOn 1 控制发布事件的线程,subscribeOn 2 控制 doOnSubscribe 的线程,subscribeOn 3 是多余的。
另外除了 doOnSubscribe 以外,还有对应的 doOnNext,doOnComplete,doOnError,这三个方法的线程始终与发布事件的线程相同。

observeOn作用范围是从它开始往下,如果多次调用 observeOn,下游的线程为从上往下,离它最近的那个 observeOn 指定的线程

Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        System.out.println("emit 1 thread " + Thread.currentThread().getName());
        e.onNext("friend");
        e.onComplete();
    }
}).subscribeOn(Schedulers.newThread())
        .observeOn(Schedulers.newThread())// observeOn 1
        .map(new Function<String, Integer>() {
            @Override
            public Integer apply(String o) throws Exception {
                System.out.println("map thread " + Thread.currentThread().getName());
                return 10;
            }
        })
        .observeOn(Schedulers.newThread())// observeOn 2
        .observeOn(AndroidSchedulers.mainThread())// observeOn 3
        .subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("A onSubscribe thread " + Thread.currentThread().getName());
            }
            @Override
            public void onNext(Integer o) {
                System.out.println("A onNext o " + o + " thread " + Thread.currentThread().getName()
            }
            @Override
            public void onError(Throwable e) {
                System.out.println("A onError" + e + " thread " + Thread.currentThread().getName());
            }
            @Override
            public void onComplete() {
                System.out.println("A onComplete thread " + Thread.currentThread().getName());
            }
        });
//打印结果
System.out: A onSubscribe thread main
System.out: emit 1 thread RxNewThreadScheduler-1
System.out: map thread RxNewThreadScheduler-2
System.out: A onNext o 10 thread main
System.out: A onComplete thread main

observeOn 1 控制 map 操作的线程,map 操作符是一个中间商,拦截上游的数据,进行加工后再返回给下游
observeOn 2 是多余的。
observeOn 3 控制接受事件的线程。

参考

https://www.jianshu.com/p/8818b98c44e2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值