Rx java 在Android上,订阅者的onComplete方法是在后台线程上按房间调用的吗?
我正在用Room实现一个Android应用程序。目前,我已经将Guave和Jetpack库包含在我的项目的其他部分中。但是,如果这有助于解决我的问题,我不介意包含另一个库(即JxJava)。然而,我还没有找到任何关于我的问题的权威文件 我需要对数据形成一个异步的、可观察的查询,并且观察处理程序必须在后台线程上运行,因为我必须对结果进行一些代价高昂的后处理 对于Java,有两种与room异步交互的方式:使用Rxjava或Guava/LiveData(请参阅) 如果我想要一个异步的一次性(与可观察的相反)查询并获取Guava/LiveData,那么API将返回一个Rx java 在Android上,订阅者的onComplete方法是在后台线程上按房间调用的吗?,rx-java,android-room,android-livedata,threadpoolexecutor,Rx Java,Android Room,Android Livedata,Threadpoolexecutor,我正在用Room实现一个Android应用程序。目前,我已经将Guave和Jetpack库包含在我的项目的其他部分中。但是,如果这有助于解决我的问题,我不介意包含另一个库(即JxJava)。然而,我还没有找到任何关于我的问题的权威文件 我需要对数据形成一个异步的、可观察的查询,并且观察处理程序必须在后台线程上运行,因为我必须对结果进行一些代价高昂的后处理 对于Java,有两种与room异步交互的方式:使用Rxjava或Guava/LiveData(请参阅) 如果我想要一个异步的一次性(与可观察的
ListenableFuture
(请参阅)。ListenableFuture
将Runnable
作为侦听器,该侦听器与执行器关联,该执行器用于在数据更改时分派侦听器(请参阅)。这很好,因为我的应用程序中已经有一个用于后台任务的中央ThreadPool
executor。然而,这是一个我不想要的一次性查询
与Guava/LiveData结合使用的异步、可观察的查询返回一个LiveData
(请参阅)。这很遗憾,因为LiveData
的Observer
方法总是在主(GUI)上执行线程。这是LiveData
的设计原则,因为它们应该更新UI,但这不是我需要的。当然,我可以在主线程上使用onChange
方法,在我的后台执行器上调度一个Runnable
,然后再次跳转到后台,但这似乎涉及到不必要的问题上下文在背景和主踏板之间切换
因此我考虑使用RxJava。与RxJava结合使用的异步、可观察的查询返回一个可流动的。可以使用使用者订阅可流动的。但是,我没有找到任何关于使用者的接受方法在哪个线程上被调度的信息Flowable
发出了一个新的值。根据RxJava文档,这是Flowable
的创建者的责任,因为RxJava只定义了抽象接口,但没有规定具体的实现。在本例中,Flowable
的创建者是Room library,但它似乎是und文档化,房间使用哪个线程作为可流动的
Room是否使用主线程更新其可流动
?(这很糟糕,与LiveData
相比没有任何改进)。Room是否使用与数据库查询相同的后台线程更新其可流动
(这不是很糟糕,但仍然可以改进。)或者Room分叉了一个只用于更新其可流动性的新线程吗?(好)
好处:为了减少分叉和被破坏的线程的数量,如果Room能够使用我的应用程序范围内的ThreadPoolExecutor
,不仅用于Flowables
,还用于它的查询和所有其他异步任务,我将不胜感激。您在文档中找不到的东西,总是可以在源代码中找到:D
假设有这样的疑问:
@Query("SELECT * FROM table")
fun query(): Flowable<List<Entity>>
示例
下面的代码
dao.query().subscribe({
Log.d("CheckThread1", "onSuccess ${Thread.currentThread().name}")
}, {
Log.d("CheckThread1", "onError ${Thread.currentThread().name}")
})
将导致:
D/CheckThread1: onSuccess arch_disk_io_0
如您所见,此操作不是在主线程上处理的
是的,您可以在构建数据库时设置自己的执行器:
Room.databaseBuilder(
context.applicationContext,
Database::class.java,
"main.db"
)
.setTransactionExecutor(.../*your executor*/)
.setQueryExecutor(.../*your executor*/)
.build()
感谢您给出的精彩回答“文档中找不到的东西,总是可以在源代码中找到”。这是真的。不幸的是,这是真的。IMHO,这应该是文档的一部分,并将好的文档与某种文档区分开来。不幸的是,今天的大多数文档只是重复从方法签名中得出的结论,但没有解释它们的依赖性和未说出的假设。以及尽管如此,Android的开发者文档与其他人相比仍然非常好。
dao.query().subscribe({
Log.d("CheckThread1", "onSuccess ${Thread.currentThread().name}")
}, {
Log.d("CheckThread1", "onError ${Thread.currentThread().name}")
})
D/CheckThread1: onSuccess arch_disk_io_0
Room.databaseBuilder(
context.applicationContext,
Database::class.java,
"main.db"
)
.setTransactionExecutor(.../*your executor*/)
.setQueryExecutor(.../*your executor*/)
.build()