添加suspend关键字后Room返回Flow的Observable查询报错是什么原因?
错误原因
你编译报错的核心原因是:返回类型为Kotlin Flow的Room DAO查询方法,不允许添加suspend关键字。
- Room对可观察查询的逻辑是:当方法返回值声明为
Flow类型时,注解处理器会自动将其识别为可观察查询,内部自动处理后台线程调度、数据库变更监听、数据异步发射逻辑,不需要开发者额外添加suspend修饰。 - 你给方法加了
suspend之后,Room的注解处理器会将其识别为单次执行的挂起查询,无法将查询返回的Cursor转换为Flow类型的返回值,就会抛出你遇到的类型转换错误。
修复方案
1. 保留Flow可观察能力的修改
直接去掉DAO方法的suspend修饰即可:
@Transaction @Query("SELECT * FROM table WHERE status = :status LIMIT 1") fun getWithSpecificStatus(status: String): Flow<MyModel?>
如果你的需求是只获取一次数据,当前的调用代码可以正常运行。如果你需要持续监听数据库变更同步更新UI,可以直接使用Flow转LiveData的扩展方法简化调用代码:
val modelLiveData: LiveData<MyModel?> = databaseService.getWithSpecificStatus(Enum.IN_PROGRESS.status) .asLiveData(Dispatchers.IO)
2. 仅需要单次查询的修改
如果你不需要观察数据变化,只是单次读取数据,也可以去掉返回值的Flow包装,保留suspend关键字:
@Transaction @Query("SELECT * FROM table WHERE status = :status LIMIT 1") suspend fun getWithSpecificStatus(status: String): MyModel?
对应的调用代码不需要调用first(),直接接收返回值即可:
val modelLiveData: LiveData<MyModel?> = liveData(Dispatchers.IO) { val result = databaseService.getWithSpecificStatus(Enum.IN_PROGRESS.status) result?.let { emit(it) } }
内容的提问来源于stack exchange,提问作者Marian Pavel
相关产品推荐
相关产品推荐

