在 Jetpack Compose 中使用 Flow 和 LiveData 运行第一个应用程序时,房间数据库未返回预填充的数据

问题描述 投票:0回答:1

我在 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")
                            }
                        )
                    }
                }

}
android kotlin android-jetpack-compose android-room android-livedata
1个回答
0
投票

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())
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.