Комнатный LiveData наблюдатель (onChange) срабатывает несколько раз, но только для INSERT - PullRequest
0 голосов
/ 27 мая 2018

Я заметил странное поведение из библиотеки комнат 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 голосов
/ 31 мая 2018

, хотя я не до конца понимаю, я нашел решение!

Моя проблема заключалась в том, что я звонил observe() из onNewIntent(), и что мой вызов выглядит так:

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

причина, по которой я звонил с onNewIntent(), заключается в том, что это действие можно открыть практически из любого места в моем приложении, используя флаг BRING_TO_FRONT (или как там его называют), поэтому onCreate() не гарантированно будет вызываться такя решил, что лучше убедиться, что наблюдатель вызван, введя его в onNewIntent().я посмотрел на документы, которые они говорят

Если указанный владелец, кортеж наблюдателя уже есть в списке, вызов игнорируется.

, поэтому я подумал, что я в безопасности.По какой-то причине я не смог понять, что каждый раз я создаю нового наблюдателя с ключевым словом new.что комбинация вызова его из onNewIntent() привела к множеству дубликатов наблюдателей, что вызвало запуск метода onChanged() несколько раз (ну, на самом деле он вызывался только один раз, , но один раз для наблюдателя! ).

как только я переместил вызов observe() на onCreate(), проблема была устранена, и я получил один вызов на onChanged(), даже когда я вставил несколько элементов в свою таблицу.

однако это все еще не объясняет, как метод delete вызывался только один раз для нескольких ...

...