文章目录
前言
这篇文章主要编写的是我在工作中使用Rxjava后遇见的常见问题,本身不对源码进行剖析。
应用场景
场景一:访问api后,配置将创建耗时任务。
这个场景是我在使用阿里云OSS的服务时候,需要在后端获取到创建阿里云安卓端上传类OSSClient
的参数。但是,在创建过程中发现Oss报错NetworkOnMainThreadException
的异常。通过阿里云官方文档了解到OssClient
的对象,需要在线程中去创建。看了这篇文章《Android:随笔——RxJava的线程切换》后,作者在文章中提出一个知识点:
总所周知 RxJava 在切换线程时用到了两个方法 subscribeOn() 和 observeOn() 下面来分别解释一下这两个方法:
- subscribeOn() : 影响的是最开始的被观察者所在的线程。当使用多个 subscribeOn() 的时候,只有第一个 subscribeOn() 起作用;
- observeOn() : 影响的是跟在后面的操作(指定观察者运行的线程)。所以如果想要多次改变线程,可以多次使用 observeOn;
/**
* 初始化Oss客户端
* @param initCallBack
*/
public void initOSSClient(InitCallBack initCallBack) {
RepositoryManager.getInstance()
.obtainApiService(UploadDataApiService.class)
.getStsToken(1000)
.compose(RxUtil.transformerBaseResponse())
.map(stsTokenBean -> providerOssClient(stsTokenBean))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BackgroundSubscriber<OSS>() {
@Override
public void onSuccess(OSS oss) {
mOss = oss;
ToastUtil.showShort("mOss");
if (initCallBack != null) {
initCallBack.onSuccess();
}
}
@Override
public void onError(Throwable e) {
super.onError(e);
initCallBack.onError(e.getMessage());
}
});
}
查看运行结果日志:
日志的打印在providerOssClient
函数中,这里我就不贴了。上面的代码中我们将subscribeOn
和observeOn
方法放在map
之后,这里通过上面的知识点,他的最初是的被观察者的线程还是运行在io
线程中。如果我们将方法放在map之前,map会受到observeOn
方法的影响,运行在主线程中,这样就会导致报错。
场景二:查询数据库中,抛出异常后,是什么流程
今天我在直接查询数据库中,主动向上抛出异常交给Rxjava来处理,但是突然报错了闪退了,犹豫我明明将进行了try-catch还会报错。我很诧异,特此将此分析记录下来。
DBDbHelper.getInstance()
.openRx()
.concatMap((Func1<SQLiteDatabase, Observable<List<WXMessage>>>) sqLiteDatabase -> {
return RxUtil.createData(WxMessageDao.getInstance()
.queryWxTMessage(sqLiteDatabase));
})
.compose(RxUtil.transformerScheduler())
.subscribe(new WxSubscriber<List<WXMessage>>() {
@Override
public void onSuccess(List<WXMessage> wxMessages) {
ToastUtil.showShort("wxMessages.size" + wxMessages.size());
}
@Override
public void onFailure(String msg) {
}
});
上面的代码封装好了,流程是两步:
- 使用Litepal查询本地数据库作为条件。
- 条件满足后触发查询另外一个数据库。
我在执行第一个流程的时候就报错了,然后我将异常抛给了Rxjava处理。debug了下,看了下堆栈信息。
上面的高亮出是Rxjava框架会将异常先给SafeSubscriber来处理,流程可以看代码注释。
protected void _onError(Throwable e) {
RxJavaPluginUtils.handleException(e);
try {
/*
* 1.actual是自定义Subscriber。
* 2.若定义出现了异常,则抓获交给SafeSubscriber的机制来处理。
*/
actual.onError(e);
} catch (