2

Мы сохраняем копию состояния сервера некоторых элементов локально в нашем приложении. Когда мы получаем новые данные с сервера, элементы могут быть изменены, удалены или вставлены. Когда данные синхронизируются, все текущие данные извлекаются с сервера.Синхронизация базы данных SQLite без возникновения нескольких onChange

Местный список:
Пункт 1, прогресс 23
Пункт 2, прогресс 75
Пункт 3, прогресс 88

Удаленный список: (пункт 2 был удален)
Пункт 1, прогресс 55
Пункт 3, ход 88
Пункт 4, ход 1 (NEW)

Текущее решение очищает стол, а затем вставляет все предметы следующим образом:

// Remove old content (this is to prevent dead items being left) 
    mContentResolver.delete(URI_TO_TABLE, null, null); 

    // Insert all new items 
    // Most existing items are changed in a sync, hence we may just insert them again instead of updating 
    final ContentValues[] inserts = new ContentValues[newItems.size()]; 
    for (int i = 0; i < newItems.size(); i++) { 
     inserts[i] = getChallengeContentValues(newItems.get(i)); 
    } 
    mContentResolver.bulkInsert(URI_TO_TABLE, inserts); 

Проблема здесь состоит в том, что мы также используем ContentObserver, который рассылает два onChange() каждый раз (один для удаления и один для bulkInsert), в результате чего наш пользовательский интерфейс для первого обновления, когда таблица очищается, опустошая наш список элементов и сразу после обновления со свежеисследованным списком, снова заполняя представление. Это вызывает много уродливого моргания.

Есть ли вообще-нибудь, чтобы просто получить один onChange()? Кажется, что applyBatch() генерирует один onChange() за операцию. Можете ли вы как-то сказать ContentProvider угрожать связкой обновлений, как только один?

ИЛИ есть ли другой способ в основном взять новый список (удаленный) и сохранить его в базе данных?

ответ

0

Как вы упомянули, applyBatch() - это правильный способ сделать это. Создайте ContentProviderOperation для каждой транзакции добавления/обновления/удаления, сохраните их как ArrayList<ContentProviderOperation> operations и запустите их как в одной операции applyBatch().

http://developer.android.com/reference/android/content/ContentProvider.html#applyBatch%28java.util.ArrayList%3Candroid.content.ContentProviderOperation%3E%29

Если ваша таблица огромна, и вы не хотите, чтобы накладные расходы из applyBatch() и необходимости должны использовать bulkInsert(), то вы можете добавить какое-то хак как добавление статиста в удалении запроса будет бы поручить поставщику не запускать notifyDataSetChanged()