安卓:如何在不观察LiveData的情况下获取其值

8

引用块

我有单独的类来处理数据获取(使用Room),通常我从中返回LiveData对象列表并对其进行更新。现在我有一个设置类,当我按下“备份”时,我想将返回的数据存储在ViewModel中,但问题是为了获取该值,我需要观察LiveData对象列表。我不想观察它,因为我只需要值(对象列表)来执行备份。 我尝试了以下方法:

DAO

@Query("SELECT * FROM $DATABASE_TABLE_GOAL")
suspend fun getAllGoals_NotLive(): List<Goal>

视图模型
var goals_NotLive: List<Goal> = ArrayList()

fun getGoalsNotLive(){
    _uiScope.launch {

        withContext(Dispatchers.IO) {
            goals_NotLive = database.goalDao.getAllGoals_NotLive()
        }
    }
}

活动

fun getGoals(): List<Goal>{
    _viewModel.getGoalsNotLive()
    return _viewModel.goals_NotLive
}

但仍返回大小为 0。我该怎么办?

2
如果getValue()返回null,则说明您的LiveData尚未有任何数据。在DAO上添加另一个实现阻塞调用的方法,然后将其用于备份(必须在后台线程中执行)。 - CommonsWare
请问能否分享一些代码作为答案呢? - Mervin Hemaraju
1个回答

10

现在,您有一个DAO,其中包含以下函数:

@Query("...")
fun gimmeData(): LiveData<SomethingOrAnother>

为了执行查询,这需要您观察 LiveData。但在某些情况下,您可能不希望如此。因此,您需要另一个函数。

一种选择是使用该函数的同步版本:

@Query("...")
fun gimmeDataSync(): SomethingOrAnother

现在,您不需要观察 LiveData。但是您需要在后台线程上调用gimmeDataSync()

或者,由于您正在使用Kotlin,您可以添加Room依赖项以支持协程,并使用以下代码:

@Query("...")
suspend fun gimmeDataAsync(): SomethingOrAnother

再次强调,不需要观察 LiveData。您需要在协程内部调用 gimmeDataAsync(),例如使用 ViewModel 上的 viewModelScope

viewModelScope.launch(Dispatchers.Main) {
  val something = dao.gimmeDataAsync()
  // TODO do something with something
}

1
这仍然无法正常运作。我已经在上面更新了一些代码,请帮助我。 - Mervin Hemaraju
它不是返回 null,而是返回大小为 0。我改变了我的问题,抱歉。 - Mervin Hemaraju
1
@MervinHemaraju:launch()与调用者异步执行。getGoals()调用getGoalsNotLive(),该函数立即返回。因此,您的launch()块尚未执行,更不用说您的IO块了。所以,您的var仍然是一个空列表。去掉var。去掉getGoals()。在viewmodel中使用database.goalDao.getAllGoals_NotLive()的结果。如果需要进行后台工作(例如将数据保存到磁盘),请在IO块中执行。如果需要在主应用程序线程上执行工作,请在launch块中执行。 - CommonsWare
@CommonsWare 我收到了“冗余的'suspend'修饰符”的建议。此外,当我通过数据库检查器更改数据库行时,UI中的值没有更新。 - AskQ
@AskQ:我建议您在Stack Overflow上提出单独的问题,并附上您自己的[mcve],展示您得到这些结果的代码。 - CommonsWare
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接