使用 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 使用干净的架构,我调用了在后台线程中进行该操作的用例。
更多信息:
类 的参与者是:
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
我在访问我的应用程序中的 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 使用干净的架构,我调用了在后台线程中进行该操作的用例。
更多信息:
类 的参与者是:
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