Room LiveData观察者(onChange)多次触发但仅针对INSERT

时间:2018-05-27 07:43:25

标签: android android-sqlite sql-insert android-room android-architecture-components

我注意到了android房间库中的一些奇怪的行为(至少它对我来说很奇怪)。

虽然还有其他帖子有类似的问题,但其中没有一个(我能找到的)与此完全相同。

我的问题是,当我观察LiveData物体时,我的观察者会发现onChange()方法被多次调用,但仅用于INSERT操作。对于我插入的每个对象,该方法将被触发一次(即,如果我插入N个对象的列表,它将被触发N次),而对于其他操作(例如DELETE),无论列表的大小如何,它都会被触发一次我正在删除。

我的DAO中有以下查询:

@query("select * from myTable")
LiveData<myEntity> getAll();

@insert
void insert(List<myEntity> entities);

@delete
void delete(List<myEntity> entities);

我正在观察getAll()方法,我肯定会一次调用delete()insert()方法 - 就像这样:

public void insertAll(List<myEntity> items)
{
    myDao.insert(items);
}

public void deleteAll(List<myEntity> items)
{
    myDao.delete(items);
}

因为在我的onChange()方法中,我正在更新用户可见的RecyclerView适配器,这是一个问题,因为我得到了很多重复项,而且我正在做其他一些事情。每次表格更改时应该只执行一次,而是多次执行(正如我已经说过,每插入一个项目一次)。

我已阅读此文并试图实施7号提示,但问题仍然存在。 https://medium.com/google-developers/7-pro-tips-for-room-fbadea4bfbd1

这是设计并考虑正常行为吗?我可以做些什么来让我的观察者只为每次INSERT操作触发一次(即使我同时插入多个对象)?

1 个答案:

答案 0 :(得分:1)

虽然我不完全理解它,但我找到了解决方案!

我的问题是我从observe()拨打onNewIntent(),我的电话看起来像这样:

 mViewModel.getAll().observe(this, new Observer<ArrayList<MyObject>>()...);

我从onNewIntent()调用此内容的原因是,此活动可以使用标记BRING_TO_FRONT(或其他任何名称)从我的应用中的几乎任何位置打开,因此onCreate()不是保证被调用所以我想我最好确保通过将它放入onNewIntent()来调用观察者。 我看了他们说的文件

  

如果给定的所有者,观察者元组已经在列表中,则呼叫为   忽略。

所以我认为我很安全。我出于某种原因未能意识到的是,我实际上每次都使用new关键字创建一个新的观察者。通过从onNewIntent()调用它导致多个重复观察者的组合导致onChanged()方法被多次触发(实际上它只被调用一次,但是每个观察者一次!)。

一旦我将observe()电话移至onCreate(),问题就解决了,即使我在桌子上插入多个项目,我也只能拨打onChanged()

然而,这仍然没有解释delete方法如何仅为多个... {/ p>调用一次