Android 房间:无限添加和删除作品
Android Room: Adding and removing works infinitely
我在项目 RecyclerView
、Room DB
中使用,并尝试创建一个函数以将记录添加到 table 或通过单击按钮删除(如果存在)。但主要问题是函数会无限执行(添加、删除并再次执行)。
代码如下:
片段
override fun saveDeleteCover(image: ImageView, cover: Cover) {
viewModel.checkIfCoverInDatabase(cover).observe(viewLifecycleOwner, { savedCover ->
//If savedCover is null then save item to table. Otherwise remove
if(savedCover == null) {
viewModel.saveCover(cover)
Toast.makeText(context, "Added to favorite", Toast.LENGTH_SHORT).show()
} else {
viewModel.deleteCover(cover)
Toast.makeText(context, "Removed from favorite", Toast.LENGTH_SHORT).show()
}
})
}
ViewModel
fun saveCover(cover: Cover) = viewModelScope.launch {
coverRepository.upsert(cover)
}
fun deleteCover(cover: Cover) = viewModelScope.launch {
coverRepository.deleteCover(cover)
}
fun checkIfCoverInDatabase(cover : Cover) = coverRepository.checkCoverInDb(cover.textId)
存储库
suspend fun upsert(cover : Cover) = db.coversDao().upsert(cover)
suspend fun deleteCover(cover: Cover) = db.coversDao().deleteCover(cover)
fun checkCoverInDb(textId: String) : LiveData<Cover> {
return db.coversDao().checkCover(textId = textId)
}
和DAO
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun upsert(cover : Cover) : Long
@Delete
suspend fun deleteCover(cover: Cover)
@Query("SELECT * FROM covers WHERE textId=:textId")
fun checkCover(textId: String) : LiveData<Cover>
您的 saveDeleteCover
函数可能不需要反应模式,liveData
。目前你得到无限 save/remote 操作的原因是:
- 检查数据库发出新值 -
null
- 您保存
cover
- 再次触发检查数据库,并发出新的 -
cover
- 你删除
cover
然后从第 1 步开始重复这些步骤。
我怀疑您正在尝试 favorite/unfavorite 基于点击的项目,因此您只需调用:
override fun saveDeleteCover(image: ImageView, cover: Cover) {
if(viewModel.checkIfCoverInDatabase(cover).value == null) {
viewModel.saveCover(cover)
Toast.makeText(context, "Added to favorite", Toast.LENGTH_SHORT).show()
} else {
viewModel.deleteCover(cover)
Toast.makeText(context, "Removed from favorite", Toast.LENGTH_SHORT).show()
}
}
这样您的操作将 运行 仅针对最新值
如果函数在点击按钮之前无限执行,将观察者代码移到 onclick() 中。
好吧,您不需要检查它是否在数据库中。只需在 deleteCover 方法中传递 CoverId 和 运行 查询即可。但是,如果您有案例要检查,那么下面就是方法。您不需要实时数据通话
你的 DAO 会像
@Query("SELECT * FROM covers WHERE textId=:textId")
fun checkCover(textId: String) : Cover?
@Query("DELETE FROM covers WHERE textId=:Id")
suspend fun deleteCover(Id: String)
REPO 将是
suspend fun deleteCover(id: String) = db.coversDao().deleteCover(id)
fun checkCoverInDb(textId: String) : Cover? {
return db.coversDao().checkCover(textId = textId)
}
你的方法就像
override fun saveDeleteCover(image: ImageView, cover: Cover) {
val cover = viewModel.checkCoverInDb(cover.textId)
if(cover == null) {
viewModel.saveCover(cover)
Toast.makeText(context, "Added to favorite", Toast.LENGTH_SHORT).show()
} else {
viewModel.deleteCover(cover.textId)
Toast.makeText(context, "Removed from favorite", Toast.LENGTH_SHORT).show()
}
}