今天解析数据使用需要在子线程和主线程中切换,然后在错误的时候进行提示,这时候就想知道一下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
会在主线程(通常)被回调 希望有错误的地方一定纠正我一下!谢谢!