我对 Android studio 比较陌生。我正在开发一个使用蓝牙和房间数据库的项目。我使用了 Philipp Lackner 的教程(因为这篇文章是关于 Room 的,所以我链接了该教程以供参考),并发现它们很有帮助。最初工作正常,但后来我向数据库添加了一个表。我已擦除所有数据并重新开始,所以我认为这不是迁移问题。
初始表格按预期工作正常。对于新表,当我通过应用程序检查器运行查询时,它在应用程序检查器中运行良好。然而,当通过 ViewModel 调用查询(在 dao 中指定)时,它返回一个空列表。
在 DAO 内:
@Query("SELECT * FROM PropTable")
fun readPropReport(): Flow<List<PropReport>>
在视图模型中:
val _propReportsU = dao.readPropReport().stateIn(viewModelScope, SharingStarted.WhileSubscribed(500),
emptyList())
Log.i("Prop Function", "Prop Reports 'U': ${_propReportsU.value}")
日志显示返回的结果是一个空列表,但正如我所说,通过应用程序检查器运行查询时该表不为空。
如有任何帮助,我们将不胜感激,谢谢!
我遵循的房间教程:https://www.youtube.com/watch?v=bOd3wO0uFr8&ab_channel=PhilippLackner
运行查询时,我希望看到表中的值,但结果是一个空集。通过应用程序检查器运行查询会返回表中的预期值。
readPropReport
返回一个 Flow,您可以通过调用 stateIn
将其转换为 StateFlow。
StateFlow 是一种异步数据类型,表示可以随时间变化的值。它使用
emptyList()
进行初始化,直到数据库返回查询结果。
您在创建后直接记录其值,之前数据库有足够的时间来执行查询,因此您会得到一个空列表(初始值)。如果您在一段时间后再次记录该值,它将包含预期的结果。
但是 Flows 通常应该像这样
collect
编辑:
_propReportsU.collect {
Log.i("Prop Function", "Prop Reports 'U': $it")
}
现在,每当
_propReportsU
的值发生变化时,都会打印一条日志消息。对你来说应该是两次:首先是一个空列表,然后是查询的结果。请注意,collect
是一个挂起函数,因此必须从协程或另一个挂起函数中调用它。
不过,视图模型中流的常见模式与您所做的不同。通常您希望将流公开为属性,以便 UI 可以收集它:
class MyViewModel(
dao: MyDao,
) : ViewModel() {
val propReportsU = dao.readPropReport()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(500),
initialValue = emptyList(),
)
}
当您在 UI 中使用 Compose 时,流的集合将如下所示:
@Composable
fun MyComposable(myViewModel: MyViewModel = viewModel()) {
val propReports: List<PropReport> by myViewModel.propReportsU.collectAsStateWithLifecycle()
}
propReports
现在将始终包含列表的最新状态:首先为空,然后在查询完成后显示查询的结果。