RxJava的onError如果在多次的线程切换过程中被调用时的线程

今天解析数据使用需要在子线程和主线程中切换,然后在错误的时候进行提示,这时候就想知道一下onError 如果在不断切换线程的时候被回调时的线程是不是也会变换的?

对于我这种小菜鸟,先打点Log看下吧

  public void onErrorBtn(View v) {
        PtrCLog.d("RxJavaErrorThreadActivity", "onErrorBtn: ");
        Observable.empty()
                .subscribeOn(Schedulers.io())
                .map(o -> {
                    PtrCLog.d("RxJavaErrorThreadActivity", "apply: " + o);
                    printThreadName("apply");
                    return new Object();
                })
                .subscribe(new Observer<Object>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        printThreadName("onSubcribe");
                    }

                    @Override
                    public void onNext(@NonNull Object o) {
                        printThreadName("onNext");
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        printThreadName("onError");
                    }

                    @Override
                    public void onComplete() {
                        printThreadName("onComplete");
                    }
                });
    }

    private void printThreadName(String s) {
        PtrCLog.d("RxJavaErrorThreadActivity", s + ">>>>>>" + Thread.currentThread().getName());
    }
复制代码
D/RxJavaErrorThreadActivity: onSubcribe>>>>>>main
D/RxJavaErrorThreadActivity: onComplete>>>>>>RxCachedThreadScheduler-1
复制代码

哈哈,发现本次操作onSubcribe是在主线程被调用的,马上开启了一个子子线程调用

D/RxJavaErrorThreadActivity: onSubcribe>>>>>>Thread-10247
D/RxJavaErrorThreadActivity: onComplete>>>>>>RxCachedThreadScheduler-1
复制代码

看来onSubcribe是在被订阅的时候调用的,随便让创建Observable在子线程,然后在主线程调用订阅

    public void onErrorBtn(View v) {
        PtrCLog.d("RxJavaErrorThreadActivity", "onErrorBtn: ");
        new Thread(this::doRxjava).start();
    }

    private void doRxjava() {

        printThreadName("create");
        Observable<Object> map = Observable.empty()
                .subscribeOn(Schedulers.io())
                .map(o -> {
                    PtrCLog.d("RxJavaErrorThreadActivity", "apply: " + o);
                    printThreadName("apply");
                    return new Object();
                });

        new Handler(Looper.getMainLooper()).post(() -> {
            map.subscribe(new Observer<Object>() {
               ....
        }
    }
复制代码

结果

D/RxJavaErrorThreadActivity: create>>>>>>Thread-10322
D/RxJavaErrorThreadActivity: onSubcribe>>>>>>main
D/RxJavaErrorThreadActivity: onComplete>>>>>>RxCachedThreadScheduler-1
复制代码

接下来开始试下报错发生的线程

准备测试的时候发现map操作符的流程没有被执行? 原因是使用Observable.empty()好像是不会去调用map操作符的,那么为什么为什么可以调用map呢? 改成jsut 随便发送一个数据就好了,以后要自己看一下,我本来还打算有些切换线程的操作就用这个empty来,看来这样是不行的

正式开始 测试代码

    public void onErrorBtn(View v) {
        PtrCLog.d("RxJavaErrorThreadActivity", "onErrorBtn: ===============================");
        new Thread(this::doRxjava).start();

    }

    private void doRxjava() {

        printThreadName("create");
        Observable<Object> map = Observable.just(1)
                .map(integer -> {
                    PtrCLog.d("RxJavaErrorThreadActivity", "我是在subscribeOn之前的操作符,当前线程是" +
                            Thread.currentThread().getName());
                    return new Object();
                })
                .subscribeOn(Schedulers.io())
                .map(o -> {
                    printThreadName("frist");
                    return new Object();
                })
                .observeOn(AndroidSchedulers.mainThread())
                .map(o -> doSomeError(1))
                .observeOn(Schedulers.computation())
                .map(o -> doSomeError(2))
                .observeOn(Schedulers.io())
                .map(o -> doSomeError(3))
                .observeOn(Schedulers.newThread())
                .map(o -> doSomeError(4));

        new Handler(Looper.getMainLooper()).post(() -> {
            map.subscribe(new Observer<Object>() {
                @Override
                public void onSubscribe(@NonNull Disposable d) {
                    printThreadName("onSubcribe");
                }

                @Override
                public void onNext(@NonNull Object o) {
                    printThreadName("onNext");
                }

                @Override
                public void onError(@NonNull Throwable e) {
                    printThreadName("onError" + e.getMessage());
                }

                @Override
                public void onComplete() {
                    printThreadName("onComplete");
                    sConut++;
                }
            });
        });
    }

    public static int sConut = 0;

    private void printThreadName(String s) {
        PtrCLog.d("RxJavaErrorThreadActivity", s + ">>>>>>" + Thread.currentThread().getName());
    }

    private Object doSomeError(int count) {
        if (count == sConut) {
            ThrowAnyWay();
        }
        return count;
    }

    private void ThrowAnyWay() {
        sConut++;
        throw new RuntimeException("sConut==" + sConut);
    }
复制代码

第一次(没有错误发生)

D/RxJavaErrorThreadActivity: onErrorBtn: ===============================
D/RxJavaErrorThreadActivity: create>>>>>>Thread-25622
D/RxJavaErrorThreadActivity: onSubcribe>>>>>>main
D/RxJavaErrorThreadActivity: 我是在subscribeOn之前的操作符,当前线程是RxCachedThreadScheduler-1
D/RxJavaErrorThreadActivity: frist>>>>>>RxCachedThreadScheduler-1
D/RxJavaErrorThreadActivity: onNext>>>>>>RxNewThreadScheduler-1
D/RxJavaErrorThreadActivity: onComplete>>>>>>RxNewThreadScheduler-1
复制代码

第二次(主线程发送错误)

D/RxJavaErrorThreadActivity: onErrorBtn: ===============================
D/RxJavaErrorThreadActivity: create>>>>>>Thread-25629
D/RxJavaErrorThreadActivity: onSubcribe>>>>>>main
D/RxJavaErrorThreadActivity: 我是在subscribeOn之前的操作符,当前线程是RxCachedThreadScheduler-3
D/RxJavaErrorThreadActivity: frist>>>>>>RxCachedThreadScheduler-3
D/RxJavaErrorThreadActivity: onErrorsConut==2>>>>>>RxNewThreadScheduler-2
复制代码

第三次(计算线程发送错误)

D/RxJavaErrorThreadActivity: onErrorBtn: ===============================
D/RxJavaErrorThreadActivity: create>>>>>>Thread-25634
D/RxJavaErrorThreadActivity: onSubcribe>>>>>>main
D/RxJavaErrorThreadActivity: 我是在subscribeOn之前的操作符,当前线程是RxCachedThreadScheduler-5
D/RxJavaErrorThreadActivity: frist>>>>>>RxCachedThreadScheduler-5
D/RxJavaErrorThreadActivity: onErrorsConut==3>>>>>>RxNewThreadScheduler-3

复制代码

第四次(io线程发送错误)

D/RxJavaErrorThreadActivity: onErrorBtn: ===============================
D/RxJavaErrorThreadActivity: create>>>>>>Thread-25639
D/RxJavaErrorThreadActivity: onSubcribe>>>>>>main
D/RxJavaErrorThreadActivity: 我是在subscribeOn之前的操作符,当前线程是RxCachedThreadScheduler-7
D/RxJavaErrorThreadActivity: frist>>>>>>RxCachedThreadScheduler-7
D/RxJavaErrorThreadActivity: onErrorsConut==4>>>>>>RxNewThreadScheduler-4
复制代码

第四次(new线程发送错误)

D/RxJavaErrorThreadActivity: onErrorBtn: ===============================
D/RxJavaErrorThreadActivity: create>>>>>>Thread-25644
D/RxJavaErrorThreadActivity: onSubcribe>>>>>>main
D/RxJavaErrorThreadActivity: 我是在subscribeOn之前的操作符,当前线程是RxCachedThreadScheduler-8
D/RxJavaErrorThreadActivity: frist>>>>>>RxCachedThreadScheduler-8
D/RxJavaErrorThreadActivity: onErrorsConut==5>>>>>>RxNewThreadScheduler-5
复制代码

第六次(没有错误)

D/RxJavaErrorThreadActivity: onErrorBtn: ===============================
D/RxJavaErrorThreadActivity: create>>>>>>Thread-25647
D/RxJavaErrorThreadActivity: onSubcribe>>>>>>main
D/RxJavaErrorThreadActivity: 我是在subscribeOn之前的操作符,当前线程是RxCachedThreadScheduler-7
D/RxJavaErrorThreadActivity: frist>>>>>>RxCachedThreadScheduler-7
D/RxJavaErrorThreadActivity: onNext>>>>>>RxNewThreadScheduler-6
D/RxJavaErrorThreadActivity: onComplete>>>>>>RxNewThreadScheduler-6
复制代码

发现和我预期的一样,onError的回调是发生在最后的observerOn的决定的线程的。

而且通过这些Log 也表示subscribeOn可以改变上游的线程,(应该是上游至下一个切换线程的位置吧),而observerOn 是确定的下游的线程。

并且我发现如果subscibeOn如果是在observerOn的下游,那么它好像并不会生效,我不知道这是为什么,带着这个疑问去学习源码吧!

结论

onError 的回调会在最后一次观察的线程中被回调,而不是在发生错误的线程。 所以,子线程解析数据发生错误了,onError会在主线程(通常)被回调 希望有错误的地方一定纠正我一下!谢谢!

转载于:https://juejin.im/post/5a31ee3e51882526151a9c0c

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值