在已经观察到 AndroidSchedulers.mainThread() 的 Maybe 上使用 blockingGet()

Use blockingGet() on Maybe that already observes on AndroidSchedulers.mainThread()

我的应用程序的 Room 数据库封装在 RxJava2 数据访问层中,该层修改所有 Singles、Maybes 等以订阅 Schedulers.io() 调度程序,并观察 AndroidSchedulers.mainThread() 调度程序。

这被认为是一个好主意,因为如果您试图从主线程之外修改 UI,有时 Android 会出现错误行为,这是查询完成后的典型行为。

public <T> Maybe<T> flow(Maybe maybe) {
    return maybe
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}

我现在有一部分应用程序需要从数据库中同步检索元素。我的设计没有预料到这一点。当我执行#blockingGet() 时,我遇到了死锁,我在 this one.

等其他问题中读到了这一点

在我需要同步检索一些数据的极端情况下,有什么方法可以修改流以不在主线程上实际观察?或者我是否必须完全重新评估这个设计,让每个单独的调用决定哪个调度器用于 observeOn?

--

在我的 Activity 中,与 UI 元素交互时:

Book book = mBooksDataSource.getBookWithId(1L)
    .observeOn(Schedulers.io())
    .blockingGet();
Log.d(LOG_TAG, "I am here."); //Never reached

在数据源中:

public Maybe<Book> getBookWithId(long bookId) {
    return mReservoir.flow(mBooksDao.getBookWithId(bookId));
    //The reservoir is the class containing the flow method from further above.
}

在 BooksDao 中:

@Transaction @Query("SELECT ...")
public abstract Maybe<Book> getBookWithId(long bookId);

我认为 Sanlok Lee 的评论是正确的,您在主线程上调用 blockingGet()。这是忽略调度程序。因此,您可以使用 ExecutorService,或尝试以下操作:

Schedulers.io().scheduleDirect(() -> {
    final Book book = mBooksDataSource.getBookWithId(1L).blockingGet();
    //Do something with the book
});