使用 Room 和 RxJava 的 IllegalStateException

IllegalStateException using Room and RxJava

我在访问我的应用程序中的 Room DAO 时遇到问题。 即使我通过 rxjava 在后台线程中执行操作,我也会收到此错误:

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

我正在尝试通过应用程序中的 MVP 使用干净的架构,我调用了在后台线程中进行该操作的用例。

更多信息:

类 的参与者是:

RecipesPresenter.java

UpdateRecipes.java which extends from UseCase.java.

最后 RecipesLocalDataSource.java

我需要一些帮助,在此先感谢。

您使用的 just 已经采用 created/computed 值。所以基本上你在调用者线程上进行计算,然后将 结果 包装到 Observable 中。 (我无法想象为什么这种逻辑误解会经常出现,因为没有主流语言会在正则括号之间推迟计算。)

改为这样做:

@Override
public Observable<Boolean> updateRecipes(List<JsonRecipe> jsonRecipes) {
    return Observable.fromCallable(() -> {
        mRecipeDb.runInTransaction(() ->
            deleteOldAndInsertNewRecipesTransaction(jsonRecipes));
        return true;
    });
}

使用 RxJava 并不意味着你在进行异步处理,事实上 RxJava 默认是同步的。

如果你想让一个操作异步,你需要使用运算符 subscribeOn 来订阅你的 observable 成为另一个线程中的 运行,或者使用 observerOn 来指定你想要完成的操作异步。

一个例子

/**
 * Once that you set in your pipeline the observerOn all the next steps of your pipeline will be executed in another thread.
 * Shall print
 * First step main
 * Second step RxNewThreadScheduler-2
 * Third step RxNewThreadScheduler-1
 */
@Test
public void testObservableObserverOn() throws InterruptedException {
    Subscription subscription = Observable.just(1)
            .doOnNext(number -> System.out.println("First step " + Thread.currentThread()
                    .getName()))
            .observeOn(Schedulers.newThread())
            .doOnNext(number -> System.out.println("Second step " + Thread.currentThread()
                    .getName()))
            .observeOn(Schedulers.newThread())
            .doOnNext(number -> System.out.println("Third step " + Thread.currentThread()
                    .getName()))
            .subscribe();
    new TestSubscriber((Observer) subscription)
            .awaitTerminalEvent(100, TimeUnit.MILLISECONDS);
}

你可以在这里看到一些例子 https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/scheduler/ObservableAsynchronous.java