subscribeOn() 没有离开主线程

subscribeOn() not taking work off the main thread

我正在使用 RxJava2 和 Room SQLite。我的道:

@Dao
public interface HeroDao {
    @Insert
    long create(Hero hero);
}

这就是我在 RxJava2 中使用它的方式:

Observable.just((int) heroDao.create(hero))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(id -> /** do stuff **/);

但是当我 运行 应用程序时,我在 Logcat 中得到的错误是 Cannot access database on the main thread since it may potentially lock the UI for a long period of time.我已经尝试将 .allowMainThreadQueries() 附加到数据库构建器并且插入通过这样就证实了我的可观察性的正确性。看来 LiveData 和 AsyncTasks 是我可以尝试的其他方法,但是当我已经对 RxJava2 进行了大量投资时,我宁愿不去那里。

那么为什么我会收到该错误? subscribeOn(Schedulers.io()) 是否足以卸载主线程的工作?否则我该如何做到这一点?似乎有一些关于将 Room 查询转换为我缺少的可观察对象的微妙之处?

因为你使用了Observable.just。此方法只是将对象包装到 Observable 中,因此它是在实际订阅并在主线程上调用 heroDao.create(hero) 之前创建的。您应该使用 Observable.fromCallable(),或者更喜欢 Single.fromCallable。 您也可以在 DAO 中定义方法,例如 @Insert Single<Int> create(Hero hero);

有些链接可能有用:
Doing queries in Room with RxJava
7 Pro-tips for Room

@Dmitry Ikryanov 的回答是正确的,但是 你也可以使用 defer()

createQuery().subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(intger -> {
                                //do sth with intege
                            Thread.currentThread().getName());
                            },
                            Throwable::printStackTrace
                    );
              }


  public Observable<Integer> createQuery() {
    return Observable.defer(() -> {
        try {
            return Observable.just((Integer) heroDao.create(hero));
        } catch (Exception e) {
            return Observable.error(e);
        }
    });
}