常见问题
RxJava 设置默认的异常捕获
为当前进程设置默认的异常捕获
RxJavaPlugins.setErrorHandler({
error("RxJavaPlugins errorHandler", it)
})
如果未设置,下面这种情形将引发 Crash
// 没有对 onError 进行监听
Observable.create<String> {
Thread.sleep(200)
throw RuntimeException("抛异常")
}.subscribe({})
一般建议 App debug 模式运行是不设置异常捕获,及时发现代码问题,release 模式时开启。
timeout 超时机制
timeout 如果下一个项目在从其前一个项目开始的指定超时时间内未发出,则生成的 ObservableSource 将终止并通知观察者 TimeoutException
一般使用方式如下:
Observable.create<String> {
Thread.sleep(5000)
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.timeout(2000L, TimeUnit.MILLISECONDS)
.subscribe({},{
error("error",it)
})
转成同步操作时要特别注意:
// blockingFirst: TimeoutException 并不是在 2s 后抛出,而是 5s 后抛出。
Observable.create<String> {
Thread.sleep(5000)
it.onNext("1")
it.onComplete()
}.timeout(2000L, TimeUnit.MILLISECONDS).blockingFirst()
// 如果任务里面永久执行,这种方式将一直阻塞当前线程
Observable.create<String> {
while (true) {
}
it.onNext("1")
it.onComplete()
}.timeout(2000L, TimeUnit.MILLISECONDS).blockingFirst()
onNext 发射空数据
Koltin 文件里面引入 Java 文件的方法,方法返回值为 null 时,不能通过 onNext 发送
// onNext called with null. Null values are generally not allowed in 2.x operators and sources.
Observable.create<String?> {
it.onNext(TestDataSource.instance.nullStr)
it.onComplete()
}.subscribe({},{
error("error", it)
})
多线程并发访问通过 blockingFrist() 异步转同步代码
有的时候复杂业务场景,通过把多个异步操作通过 blocking 方式转同步,然后在多线程中使用,这种方式虽使代码可以逐行阅读容易理解,但带来很多潜在风险。RxJava 内部执行链路很长,对 blocking 同步的方法即使加锁,也不能保证并发可以安全执行。