Android 房间查询返回 null

Posted

技术标签:

【中文标题】Android 房间查询返回 null【英文标题】:Android Room Query returning null 【发布时间】:2021-09-01 05:58:54 【问题描述】:

我试图通过 Room 从数据库中获取值,但它总是返回 null。 它应该从 DB BalancesCat 中检索数据。 有什么帮助吗?谢谢!

这是 DAO

@Query("SELECT * FROM BalancesCat")
suspend fun getAllBalances(): List<BalancesCat>

存储库

suspend fun getAllBalancesCat(): List<BalancesCat>? 
        var balancesCat: List<BalancesCat>? = null
        withContext(Dispatchers.IO)
            balancesCat = balancesCatDao.getAllBalances()
        
        return balancesCat
    

视图模型

fun getAllBalancesCat(): List<BalancesCat>? 
        var balancesCat: List<BalancesCat>? = null
        viewModelScope.launch 
            balancesCat = repository.getAllBalancesCat()
        
        return balancesCat
    

以及我要检索数据的片段

balancesCatViewModel = ViewModelProvider(requireActivity(),
   BalancesCatViewModelFactory(requireActivity().application)).
   get(BalancesCatViewModel::class.java)

allBalancesCat = balancesCatViewModel.getAllBalancesCat()

var allBalancesCatNew: BalancesCat

val currentDate1 = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
val dateCurrent1 = Date.valueOf(currentDate1)

allBalancesCat?.forEach 
   if(it.date != dateCurrent1)
      it.date = dateCurrent1
      allBalancesCatNew = it
      balancesCatViewModel.update(allBalancesCatNew)
   

【问题讨论】:

【参考方案1】:

这不是你的问题,但我不得不提一下,你的存储库的 getAllBalancesCat() 函数是不必要的复杂,不需要返回一个可为空的。由于balancesCatDao.getAllBalances()suspend 函数,因此将其包装在withContext() 中是没有意义的。您永远不需要指定上下文来调用挂起函数(除非挂起函数设计不正确并且其中包含阻塞代码)。可以简化为:

suspend fun getAllBalancesCat(): List<BalancesCat> = balancesCatDao.getAllBalances()

您的 ViewModel 函数不正确,并保证始终返回 null。它创建初始值为 null 的变量 balancesCat,启动协程,然后在协程开始之前返回 null balancesCat。 ViewModel 范围内的协程被添加到主线程循环器的队列中,但这会将它们放在当前在主线程中运行的代码之后,就像这个函数的其余部分一样。

这个 ViewModel 函数的正确工作方式是同时作为一个挂起函数,返回一个不可为空的列表:

suspend fun getAllBalancesCat(): List<BalancesCat> = repository.getAllBalances()

在您的 Fragment 中,从 lifecycleScope 启动一个协程来完成所有这些部分涉及调用挂起函数的工作。

我不能对片段代码发表太多评论,因为它没有在上下文中显示,但我看到了一些可能的代码异味。可能应该只是函数中本地 vals 的属性。 Fragment 不需要从 ViewModel 获取值,然后将它们存储在属性中,如果需要,那么 Fragment 的代码会变得更加复杂,因为它必须检查本地属性是否包含最新值,而不是仅仅从源(ViewModel)获取它。

【讨论】:

以上是关于Android 房间查询返回 null的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中使用房间数据库写入迁移的查询错误

房间从查询返回 kotlin 元组

在房间数据库 Android 中返回带有嵌套关系的空数据

Android 房间数据库 - 不确定如何将 Cursor 转换为此方法的返回类型

Android Studio:房间:错误:找不到字段的吸气剂

房间更新查询