对每个数据库条目执行请求

问题描述

我正在尝试将使用Retrofit进行API请求的现有工作代码与Android中的sqlite Room集成。

val apiInterface = ApiInterface.create()
val requests = ArrayList<Observable<Business>>()
requests.addAll(DB.getAllBusinessEntry().map { // fun getAllBusinessEntry(): List<BusinessEntry>
    apiInterface.getBusiness(it.major,it.minor)
})
Observable.zip(requests)
{ objects ->
     val businesses = ArrayList<Business>()
     objects.forEach { businesses.add(it as Business) }
     return@zip businesses
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
    businessAdapter.updateElements(it)
}

BusinessEntry是包含主键(majorminor)的数据类,主键允许执行API请求以获取业务详细信息(存储在Business中)。 DB.getAllBusinessEntry()一个功能,该功能使用Android文档中记录的DB Helper类来访问应用程序内部的sqlite数据库

我想将此代码迁移到Room并依靠RxJava功能,但我不知道如何在BusinessEntry调用中转换每个ApiInterface

以下是BusinessDao界面

import androidx.room.Dao
import androidx.room.Query
import io.reactivex.rxjava3.core.Observable

@Dao
interface BusinessDao {
    @Query("SELECT * FROM Entry")
    fun getAll(): Observable<List<Entry>>
}

我正在使用2.3.0-alpha02室


编辑:根据评论中的建议,我已经实现了这一点,但仍然无法正常工作,因为在最后的subscribe调用中,businessList的类型为{{1} },而应为List<Observable<Business>!>!

List<Business>

解决方法

我不是RxJava的专家,但我可以建议尝试以下方法:

roomDb.businessDao().getAll()
    .flatMap { entryList -> Observable.fromIterable(entryList) }
    .flatMap { entry -> apiInterface.getBusiness(entry.major,entry.minor) }
    .toList()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe { businessList -> businessAdapter.updateElements(businessList) }

其中roomDb-是Room数据库对象的实例,roomDb.businessDao()为您提供了一个实现BusinessDao接口的自动生成类的实例(当然,如果您添加了方法{{ 1}}到Room数据库类)。您可以在documentation中阅读有关此内容的更多信息。

更新

上面使用的businessDao()运算符存在问题,因为Room的Observable创建了一个无限的流,该流等待数据的不断更新,并且永远不会完成。在this answer找到的解决方案。

toList()