簡體   English   中英

房間數據庫 - Dao - Repository - ViewModel

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM