Room LiveData 观察器 (onChange) 多次触发,但仅适用于 INSERT



我注意到android Room库的一些奇怪行为(至少对我来说看起来很奇怪(。

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

我的问题是,当我观察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 操作仅触发一次(即使我同时插入多个对象(?

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

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

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

我从onNewIntent()调用它的原因是,可以使用标志BRING_TO_FRONT(或任何它的名字(从我的应用程序中的几乎任何地方打开此活动,因此不能保证调用onCreate()所以我想我最好通过将观察者放入onNewIntent()来确保调用观察者。 我看了他们说的文档

如果给定的所有者,观察者元组已经在列表中,则调用为 忽视。

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

observe()调用移动到onCreate()后,问题就解决了,即使我在表中插入多个项目,我也会收到一个调用onChanged()

但是,这仍然不能解释为什么delete方法只被调用一次多次...

最新更新