Rx java 在Android上,订阅者的onComplete方法是在后台线程上按房间调用的吗?

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(请参阅) 如果我想要一个异步的一次性(与可观察的

我正在用Room实现一个Android应用程序。目前,我已经将Guave和Jetpack库包含在我的项目的其他部分中。但是,如果这有助于解决我的问题,我不介意包含另一个库(即JxJava)。然而,我还没有找到任何关于我的问题的权威文件

我需要对数据形成一个异步的、可观察的查询,并且观察处理程序必须在后台线程上运行,因为我必须对结果进行一些代价高昂的后处理

对于Java,有两种与room异步交互的方式:使用Rxjava或Guava/LiveData(请参阅)

如果我想要一个异步的一次性(与可观察的相反)查询并获取Guava/LiveData,那么API将返回一个
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()