Android Room Database-LiveData-更新/插入/删除,跳过观察者(回调)

时间:2018-10-08 12:56:10

标签: android database kotlin android-room android-database

我是Room Database的新用户,最近我遇到了一个问题,该问题与修改应用程序的数据库(更新/插入/删除)有关,而不会导致触发观察器中的回调。

这是我的模型的Dao类:

@Dao
interface ReceiptRowDao {

    @Query("SELECT * FROM my_model ")
    fun getMyModels(): LiveData<MutableList<MyModel>>

    @Update
    fun update(receiptRow: ReceiptRow): Int
}

我的Database班:

@Database(
        entities = [
            (MyModel::class)
        ],
        version = 1,
        exportSchema = false
)
abstract class AppDatabase: RoomDatabase() {

    abstract fun myModelDao(): MyModelDao
}

用法:

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)
                ...
            })
    }
}

MyClass中,更新指令将导致无限循环,因为对MyModel的更新将触发观察者。然后,观察者内部的代码将再次运行。这将进行另一次更新。这将再次触发观察者,依此类推...

在这种情况下,是否有一种方法可以进行模型更新,但是可以跳过可能正在监听更改的观察者?

3 个答案:

答案 0 :(得分:0)

我认为您可以做的只是简单地检查数据库中是否已存在data。喜欢

 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)
            }
            ...
        })
}

答案 1 :(得分:0)

这是保存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();
}
}

,要在数据库中插入数据的部分带有两个参数。一个数据库类对象和实体。我已将实体类设计为类似于模型类,可用于在主类中设置和获取值。

 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);

和方法setDailyDatabase只是调用数据库类以插入实体

  private void setDailyDataBase(MyDataBase dataBase, DailyConsumption dailyConsumption) {

   // query takes parameters to update respective  columns
    myDataBase.dailyConsumptionDao().updateItem(mId, mQuanity, mTime, date);
}

答案 2 :(得分:0)

对于您的问题,我建议您按照以下方式观察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)
}
}

这将帮助您将观察者逻辑更新逻辑分开,现在调用getDataObserver()方法,在其中您要观察数据并使用test()方法当您想更新模型时。