【问题标题】:IllegalStateException using Room and RxJava使用 Room 和 RxJava 的 IllegalStateException
【发布时间】:2018-04-24 08:58:24
【问题描述】:

在我的应用中访问 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 扩展自 UseCase.java

最后是RecipesLocalDataSource.java

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

【问题讨论】:

    标签: android rx-java2 android-room


    【解决方案1】:

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

    改为这样做:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        • 2018-10-14
        • 1970-01-01
        • 1970-01-01
        • 2018-06-16
        • 1970-01-01
        相关资源
        最近更新 更多