[英]Android Room Database - LiveData - Update/Insert/Delete, skip observer (callback)
I'm new in Room Database, and recently I faced a problem that has to do with modifying the App's database (update/insert/delete) without causing the callback in observer to be fired. 我是Room Database的新用户,最近我遇到了一个问题,该问题与修改应用程序的数据库(更新/插入/删除)有关,而不会导致触发观察器中的回调。
This is the Dao
class for my model: 这是我的模型的
Dao
类:
@Dao
interface ReceiptRowDao {
@Query("SELECT * FROM my_model ")
fun getMyModels(): LiveData<MutableList<MyModel>>
@Update
fun update(receiptRow: ReceiptRow): Int
}
My Database
class: 我的
Database
类:
@Database(
entities = [
(MyModel::class)
],
version = 1,
exportSchema = false
)
abstract class AppDatabase: RoomDatabase() {
abstract fun myModelDao(): MyModelDao
}
Usage: 用法:
class MyClass {
val db: AppDatabase = Room
.databaseBuilder(mContext, AppDatabase::class.java, "my_db")
.allowMainThreadQueries()
.build()
fun test() {
val myLiveData = db.myModelDao.getMyModels()
myLiveData!!.observe(this, Observer { data ->
...
val item = data.get(0)
item.id = 4
// This update should not cause a callback
db.myModelDao().update(item)
...
})
}
}
In the MyClass
, the update instruction will cause an infinite loop , since an update to MyModel, will fire the observer. 在
MyClass
,由于对MyModel的更新将触发观察者,因此update指令将导致无限循环 。 Then the code inside the observer will run again. 然后,观察者内部的代码将再次运行。 This will do another update.
这将进行另一次更新。 This will fire the observer again and so on...
这将再次触发观察者,依此类推...
In such a scenario, is there a way to do the update of a model, but to skip the observers that might be listening for changes? 在这种情况下,是否有一种方法可以进行模型更新,但是可以跳过可能正在监听更改的观察者?
I think what you could do is just simply check whether data
is already in the database. 我想你可以做的是只是简单的检查是否
data
已经在数据库中。 Like 喜欢
fun test() {
val myLiveData = db.myModelDao.getMyModels()
myLiveData!!.observe(this, Observer { data ->
...
val item = data.get(0);
// This update should not cause a callback
if (!db.myModelDao().itemExists(item){
db.myModelDao().update(item)
}
...
})
}
this is the database class which holds the DAO classes along with its instance 这是数据库类,其中包含DAO类及其实例
@Database(entities = {Weight.class, DailyConsumption.class, DrinkType.class}, version = 1, exportSchema = false)
public abstract class MyDataBase extends RoomDatabase {
// DAO classes
public abstract WeightDao weightDao();
public abstract DailyConsumptionDao dailyConsumptionDao();
public abstract DrinkTypeDao drinkTypeDao();
private static MyDataBase dataBase;
public static MyDataBase getInstance(Context context){
if (null== dataBase){
dataBase= buildDatabaseInstance(context);
}
return dataBase;
}
private static MyDataBase buildDatabaseInstance(Context context) {
return Room.databaseBuilder(context,
MyDataBase.class,
Constants.DB_NAME)
.allowMainThreadQueries().build();
}
}
and the part where you want to insert the data in database takes two parameters. 您要在数据库中插入数据的部分采用两个参数。 one database class object and the entities.
一个数据库类对象和实体。 I have designed the entities classes like a model class which you can use to set and get values inside main class.
我已将实体类设计为类似于模型类,可用于在主类中设置和获取值。
dailyConsumption = new DailyConsumption(); // entity class
myDataBase = MyDataBase.getInstance(this);
dailyConsumption.setIcon(mIcon);
dailyConsumption.setQuantity(mQuantity);
dailyConsumption.setTime(strTime);
dailyConsumption.setIsSelected(0);
dailyConsumption.setDrinkUnit(drinkUnit);
dailyConsumption.setDateTime(insertionDate);
dailyConsumption.setDate(date);
setDailyDataBase(myDataBase, dailyConsumption);
and the method setDailyDatabase just calls the database class to insert the entity setDailyDatabase方法仅调用数据库类以插入实体
private void setDailyDataBase(MyDataBase dataBase, DailyConsumption dailyConsumption) {
// query takes parameters to update respective columns
myDataBase.dailyConsumptionDao().updateItem(mId, mQuanity, mTime, date);
}
For your issue, i would suggest you following way for observing LiveData
& updation of your Model
: 对于您的问题,我建议您按照以下方式观察
LiveData
和更新Model
:
class MyClass {
val db: AppDatabase = Room
.databaseBuilder(mContext, AppDatabase::class.java, "my_db")
.allowMainThreadQueries()
.build()
fun getDataObserver() = db.myModelDao.getMyModels()
fun test(item: MyModel) {
db.myModelDao().update(item)
}
}
This will help you seperate your observer logic from update logic , now call getDataObserver()
method where you want to observe data and use your test() method when you want to update your Model. 这将帮助您将观察者逻辑与更新逻辑分开,现在在要观察数据的地方调用
getDataObserver()
方法,并在要更新模型时使用test()方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.