RxJava 使用注意事项
常见问题
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 同步的方法即使加锁,也不能保证并发可以安全执行。