База данных комнат Android - LiveData - Обновление / Вставка / Удаление, пропуск наблюдателя (обратный вызов) - PullRequest
0 голосов
/ 08 октября 2018

Я новичок в базе данных комнат, и недавно я столкнулся с проблемой, связанной с изменением базы данных приложения (обновление / вставка / удаление) без запуска обратного вызова в обозревателе.

Это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 голосов
/ 08 октября 2018

это класс базы данных, который содержит классы 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);
}
0 голосов
/ 08 октября 2018

Для вашей проблемы я бы предложил вам следующий способ наблюдения 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 (), когда вы хотите обновить вашу модель.

0 голосов
/ 08 октября 2018

Я думаю, что вы могли бы просто проверить, есть ли 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)
            }
            ...
        })
}
...