我在 Jetpack Compose 应用程序中使用 Room 数据库,并且在创建数据库时将数据预填充到数据库中。但是,当我尝试通过 DAO 中的 getAll() 函数使用 Flow 或 LiveData 获取数据时,我在第一次运行应用程序时没有收到任何数据。
奇怪的是,当我重新启动应用程序时,数据会按预期获取并显示。似乎预填充的数据不可用于第一次查询执行。
有人可以帮助我了解为什么数据最初不可用以及如何解决此问题吗?
相关代码如下:
@Dao
interface CategoryDAO {
@Query("SELECT * FROM categories")
fun getAll(): LiveData<List<CategoryEntity>>
@Insert
suspend fun insertCategory(category:CategoryEntity)
@Insert
fun insertAll(categories: List<CategoryEntity>)
@Delete
suspend fun deleteCategory(category: CategoryEntity)
}
interface CategoryRepository {
fun getAll() : LiveData<List<Category>>
suspend fun createCategory(category: Category)
suspend fun deleteCategory()
}
在 CategoryRepositoryImpl 中,我只是将数据从 CategoryEntity 映射到 Category:
class CategoryRepositoryImpl @Inject constructor(
private val categoryDAO: CategoryDAO
) : CategoryRepository {
override fun getAll(): LiveData<List<Category>> {
return categoryDAO.getAll().map { entityList ->
entityList.map { entity ->
entity.toDomain()
}
}
}
}
使用 Hilt 我实例化数据库
@Provides
@Singleton
fun provideCategoryDatabase(
@ApplicationContext appContext:Context
) : CategoryDatabase {
return Room.databaseBuilder(
appContext,
CategoryDatabase::class.java,
"categories-db"
)
.addCallback(object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
Executors.newSingleThreadExecutor().execute {
val dao = provideCategoryDatabase(appContext).CategoryDAO()
dao.insertAll(categories = prepopulateData())
}
Log.d("RoomDatabase", "Database created and prepopulated!")
}
})
.build()
}
prepopulateData() 是一个返回 List 的函数
我的 ViewModel 看起来像这样:
@HiltViewModel
class CategoryViewModel @Inject constructor(
private val categoryRepository: CategoryRepository
):ViewModel(){
val categories: LiveData<List<Category>> = categoryRepository.getAll()
}
我在我的 CategoryDialog 中使用它,如下所示:
@Composable
fun CategoryDialog(
showDialog: MutableState<Boolean>,
categoryViewModel: CategoryViewModel = hiltViewModel()
){
val categories by categoryViewModel.categories.observeAsState(emptyList())
... Rest of the UI
LazyVerticalGrid(
contentPadding = PaddingValues(20.dp),
columns = GridCells.Fixed(3),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
items(categories){
CategoryItem(
category = it,
onClick = {
// TODO("ADD FUNCTIONALITY TO SELECT CATEGORY")
}
)
}
}
}
categoryRepository.getAll()在数据插入数据库之前调用
您可以按如下方式修改viewModel。记得调用函数getCategories()
@HiltViewModel
class CategoryViewModel @Inject constructor(
private val categoryRepository: CategoryRepository
): ViewModel(){
val categories = MutableLiveData<List<Category>>(emptyList())
fun getCategories() {
viewModelScope.launch {
categories.postValue(categoryRepository.getCategories())
}
}
}