带有Room错误处理的RxJava2-数据库主线程异常

时间:2018-10-26 13:43:07

标签: android database error-handling reactive

我正在尝试从远程源检索项目,如果这不起作用(不连接互联网),我想从会议室数据库中检索缓存的项目。 我为错误发生的时间创建了一个新的单曲,并指定了应该订阅和观察的线程。我仍然是这个例外:

java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

这是检索项目的方法:

public LiveData<List<Article>> getNewsArticles() {
    return LiveDataReactiveStreams.fromPublisher(
            newsService.getNewsArticles()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())

                    .onErrorResumeNext(throwable ->
                            Single.just(newsDao.findAllForNumber(AMOUNT_OF_ARTICLES_PER_PAGE))
                                    .subscribeOn(Schedulers.io())
                                    .observeOn(AndroidSchedulers.mainThread()))

                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())

                    .doOnSuccess(newsArticles -> Completable.fromAction(() ->
                            newsDao.insertAll(newsArticles))
                            .subscribeOn(Schedulers.io()))
                    .toFlowable());
}

LiveDataReactiveStreams将其转换为livedata对象并处理订阅,因此我的视图仅了解livedata。

我似乎无法在后台线程上执行onErrorResumeNext调用。

任何帮助将不胜感激!

答案

我最终使用以下代码解决了这个问题:

public LiveData<List<Article>> getNewsArticles() {
    return LiveDataReactiveStreams.fromPublisher(
            newsService.getNewsArticles()
                    .observeOn(Schedulers.io())
                    .doOnSuccess(newsArticles -> newsDao.insertAll(newsArticles))
                    .onErrorResumeNext(throwable -> Single.fromCallable(() -> newsDao.findAllForNumber(AMOUNT_OF_ARTICLES_PER_PAGE)))
                    .toFlowable());
}

1 个答案:

答案 0 :(得分:2)

在RxJava方法subscribeOn中,指定将在其上运行Observable的Scheduler。但是方法observeOn指定了计划程序,观察者将在该计划程序上观察此Observable。

为简单起见:

{
  "presets": [
    [
      "@babel/preset-env", {
        "targets": {
          "node": "current"
        }
      }
    ]
  ]
}
or if you are using babel-preset-env package

{
  "presets": [
    [
      "env", {
        "targets": {
          "node": "current"
        }
      }
    ]
  ]
}

ObserveOn仅在下游起作用。 beforeOn之后的所有方法均已移至IO线程。而watchOn之前的方法仍在主线程中。

在您的示例中,您在某处尝试在主线程上调用room dao命令,并且系统不允许在主线程上执行。您可以在每个命令上设置断点,然后在IDE中准确查找要执行命令的线程名称。

有关更复杂的示例,请参见此article