使用Room和RxJava的IllegalStateException

时间:2018-04-24 08:58:24

标签: android rx-java2 android-room

在我的应用中访问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.javaUseCase.java延伸。

最后RecipesLocalDataSource.java

我需要一些帮助,谢谢你。

2 个答案:

答案 0 :(得分:1)

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

请改为:

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

答案 1 :(得分:0)

使用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

的一些示例