我在从
check_list_table
获取数据时遇到问题。 insert
方法正常执行,没有错误或警告,但 allItems
属性不起作用。
Item、ItemDao 和 ViewModel 类如下所示:
@Entity(tableName = "check_list_table")
data class Item(
@PrimaryKey(autoGenerate = true)
var id: Int = 0,
var title: String,
var priority: Int=0
)
interface ItemDao {
@Insert
suspend fun insert(item: Item)
@Delete
suspend fun delete(item: Item)
@Query("SELECT * FROM check_list_table ORDER BY id DESC")
fun getAllItems():LiveData<List<Item>>
}
class DailyCheckListItemViewModel(private val itemDao: ItemDao, application: Application) :
AndroidViewModel(application) {
private val viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
val allItems = itemDao.getAllItems().value
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
fun onAdd(item: Item) {
uiScope.launch {
insertItem(item)
}
}
suspend fun insertItem(item: Item) {
withContext(Dispatchers.IO) {
itemDao.insert(item)
}
}
}
insert
方法调用。insert
使用适当的 feed 调用的方法。insert
方法从非 ui 线程调用为什么我不能从数据库中获取数据[使用 allItems 属性]?
您已经定义了一个可观察的读取操作:
@Query("SELECT * FROM check_list_table ORDER BY id DESC")
fun getAllItems():LiveData<List<Item>>
但是直接阅读它:
val allItems = itemDao.getAllItems().value
这将不起作用,因为必须观察
LiveData
对象才能实际触发数据库读取。
你可以...
使读取操作成为“一次性”(不可观察)操作(如果您只需要读取一次数据)
将
DAO
更改为仅返回项目列表,而不是 LiveData
:
@Query("SELECT * FROM check_list_table ORDER BY id DESC")
suspend fun getAllItems():List<Item>
并更改
ViewModel
以一次获取所有数据:
viewModelScope.launch { allItems = itemDao.getAllItems() }
或者将
ViewModel
变量也设置为 LiveData
并在 UI 中观察它(如果数据可以更改并且您想刷新 UI)
DAO
保持不变:
@Query("SELECT * FROM check_list_table ORDER BY id DESC")
fun getAllItems():LiveData<List<Item>>
ViewModel 只是引用了
LiveData
:
val allItems = itemDao.getAllItems()
你的
Activity
/Fragment
观察到变化。现在观察到LiveData
,会触发读操作,返回数据:
viewModel.allItems.observe(/*lifecycle*/) { items ->
// Do something with the list of items that was read
}