![](/img/trans.png)
[英]returning a list of data to viewModel using Repository pattern from different data sources (network and room)
[英]Room database - Dao - Repository - ViewModel
在 Dao - Repository - ViewModel 之間編寫好的代碼。 function 始終返回 null 值。
來自實體:
@Entity(tableName = "diabete")
class Diabete(
@PrimaryKey(autoGenerate = true)
@NonNull
@ColumnInfo(name = "diabeteId")
var id: Int,
var date: LocalDateTime,
var balise: String,
var taux: Float,
var note: String
)
來自道:
// Obtenir la moyenne du taux selon la balise
@Query("SELECT IFNULL(avg(taux), 0.0) FROM diabete WHERE balise = :balise")
fun avgByBalise(balise: String): LiveData<Float>
來自存儲庫:
fun avgBaliseAJeun(balise: String): LiveData<Float> {
return dbDao.avgByBalise(balise)
}
從視圖模型:
fun avgBaliseAJeune(balise: String): LiveData<Float> {
val result = MutableLiveData<Float>()
viewModelScope.launch(Dispatchers.IO) {
val retour = repository.avgBaliseAJeun(balise)
result.postValue(retour.value)
}
return result
}
來自片段:
val avgBaliseAJeun: Float = dpViewModel.avgBaliseAJeune("À jeun").observeAsState(initial = 0F).value
這一行在調試的時候總是返回null。
編譯一切正常。
應用程序在運行時崩潰。
什么東西少了?
恭喜您提出第一個問題,歡迎!
一個(不太)有趣的事情是 LiveData 值可以是 null 即使聲明為不可為空的源。
要記住的第二件事是,在應用程序啟動時,來自 room 的實時數據有輕微的滯后,這意味着即使數據在 Room 中,它最初也將是 null,如上所示。 當您獲取它的值時,您會看到它是 null。從直覺上講,您可以像這樣使用它,但它不支持那樣。
相反,它應該像這樣在 Activity 和 Fragments 中使用:
dpViewModel.avgBaliseAJeune("À jeun").observe(this, result -> {
//Do something with 'result'
});
或者,如果您想使用 Jetpack Compose,那么您可以使用類似
val avgBaliseAJeun by dpViewModel.avgBaliseAJeune("À jeun").observeAsState()
最后我看到你的 viewModel 代碼正在將實時數據轉換為可變實時數據,但我建議使用實時數據作為只讀 pipe 從 repostiory/Room 流出。 然后單獨做一個function通過Dao插入/更新到Room來改變值。 您可以在代碼的任何位置執行此操作,然后實時數據將觀察到這些更改。
Google 有一些很棒的代碼實驗室來檢查一些帶有 Room、LiveData、Flow、ViewModel 的示例(盡管並不總是一次)。 也請隨時在這里跟進!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.