在可能已在AndroidSchedulers.mainThread()

时间:2019-05-23 18:21:04

标签: android rx-java2 rx-android

我的应用程序的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,我已经读过死锁。

有什么方法可以将流修改为实际上不观察吗?在边缘线程中,我需要同步检索一些数据?还是我必须完全重新评估该设计,以使每个单独的调用都可以确定使用哪个Scheduler来进行观察?

-

在我的活动中,与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);

1 个答案:

答案 0 :(得分:1)

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

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