我注意到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
方法只被调用一次多次...