Android Studio:为什么无法从房间数据库表中检索信息?

问题描述 投票:0回答:1

我对 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

运行查询时,我希望看到表中的值,但结果是一个空集。通过应用程序检查器运行查询会返回表中的预期值。

android kotlin android-room android-database
1个回答
0
投票

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
现在将始终包含列表的最新状态:首先为空,然后在查询完成后显示查询的结果。

© www.soinside.com 2019 - 2024. All rights reserved.