3分钟让你明白observeOn和subscribeOn的关系!

我最近在看rxJava,也是出了将近两年的框架了,感觉有必要学习一下,今天碰到这么个问题,observeOn和subscribeOn到底什么关系?看了很多大神的博客,也问了公司的大神,都没有给我讲明白。到最后直接一个demo解决问题。(要是不想看demo可以直接看最后的结论,推荐看demo的时候自行查阅observeOn和subscribeOn的源码,相信大家都学到现在,看看源码应该不是什么问题)

Observable.create(new Observable.OnSubscribe<String>() {
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        subscriber.onNext("-->robin");
                        subscriber.onCompleted();
                        Log.i("robin","0-->"+Thread.currentThread().getName());
                    }
                })
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {
                        Log.i("robin","1-->"+Thread.currentThread().getName());
                        return s;
                    }
                })

                .subscribeOn(Schedulers.io())

                .map(new Func1<String, String>() {
                    @Override
                    public String call(String o) {
                        Log.i("robin","2-->"+Thread.currentThread().getName());
                        return o;
                    }
                })

                .observeOn(AndroidSchedulers.mainThread())

                .map(new Func1<String, String>() {
                    @Override
                    public String call(String o) {
                        Log.i("robin","3-->"+Thread.currentThread().getName());
                        return o;
                    }
                })

                .observeOn(Schedulers.io())
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String o) {
                        Log.i("robin","5-->"+Thread.currentThread().getName());
                        return o;
                    }
                })

                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String o) {
                        Log.i("robin","4-->"+Thread.currentThread().getName()+o);
                    }
                });

代码很简单,然后直接上log,如下图:

这里写图片描述

类似的,还有很多排列组合的方式,大家自行组合,因为我不想占用大家太多的时间了优快云的数据库大小。

结论

1 observeOn修改的是他 下面 的代码执行的线程
subscribeOn修改的是他 上面 执行代码的线程
2 observeOn之后在调用observeOn还可以修改线程,但是调用subscribeOn就不能再修改线程
subscribeOn之后在调用observeOn还可以修改线程,但是调用subscribeOn就不能再修改线程

在 RxJava 中,`subscribeOn` `observeOn` 是用于线程切换的重要操作符,它们在处理异步任务线程调度时具有不同的行为适用场景。 ### `subscribeOn` 的作用与使用场景 `subscribeOn` 用于指定 **被观察者(Observable)** 的创建及发射事件所处的线程。这意味着,从 `Observable` 的创建开始,直到第一个 `observeOn` 出现之前,所有的操作符(如 map、filter 等)都会在 `subscribeOn` 所指定的线程中执行。通常,它用于将耗时操作(如网络请求、数据库查询等)从主线程中移出,以避免阻塞 UI 线程[^2]。 例如: ```java Observable.just("data") .map(s -> s + "-processed") .subscribeOn(Schedulers.io()) .subscribe(result -> { // 在 io 线程中执行 map 操作 System.out.println(result); }); ``` 在上述代码中,`Observable.just` `map` 操作都在 `Schedulers.io()` 线程中执行。 ### `observeOn` 的作用与使用场景 `observeOn` 用于指定 **后续操作符以及观察者(Observer)** 所在的线程。与 `subscribeOn` 不同,`observeOn` 只影响它之后的操作符观察者的执行线程,而不是整个数据流的起始线程。它常用于在执行完耗时操作后,将结果切换回主线程(如 Android 中的 `AndroidSchedulers.mainThread()`)以便更新 UI[^3]。 例如: ```java Observable.just("data") .map(s -> s + "-processed") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { // 在主线程中更新 UI textView.setText(result); }); ``` 在此例中,`map` 操作仍然在 `Schedulers.io()` 线程中执行,而 `textView.setText(result)` 则在主线程中执行。 ### 区别总结 | 特性 | `subscribeOn` | `observeOn` | |------|----------------|--------------| | 作用对象 | 被观察者(Observable) | 观察者(Observer)后续操作符 | | 影响范围 | 从 `Observable` 创建开始直到第一个 `observeOn` | 从调用 `observeOn` 开始直到下一个 `observeOn` | | 常用场景 | 将耗时操作切换到子线程(如 IO、计算) | 将结果切换到主线程(如 UI 更新) | | 线程切换次数 | 通常只调用一次 | 可多次调用以切换不同阶段的线程 | ### 使用建议 - **避免在 `PublishSubject` 中误用 `subscribeOn`**:`subscribeOn` 并不会改变 `PublishSubject` 发射事件的线程,它的作用仅限于 `Observable` 的创建阶段。因此,在使用 `PublishSubject` 时,应特别注意线程切换的实际效果[^2]。 - **合理组合使用 `subscribeOn` `observeOn`**:通常的做法是使用 `subscribeOn(Schedulers.io())` 来处理后台任务,然后通过 `observeOn(AndroidSchedulers.mainThread())` 将结果返回主线程进行 UI 更新。 ### 示例代码 ```java Observable.create((ObservableOnSubscribe<String>) emitter -> { // 在 io 线程中执行 String result = fetchDataFromNetwork(); emitter.onNext(result); }) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.computation()) .map(data -> { // 在 computation 线程中执行 return processData(data); }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { // 在主线程中更新 UI updateUI(result); }); ``` 在上述代码中,数据获取在 `io` 线程中进行,数据处理在 `computation` 线程中进行,最终结果在主线程中用于更新 UI。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值