Запретить петлю синхронизации сети при синхронизации из сети в Android ContentProvider - PullRequest
14 голосов
/ 06 июля 2011

Я пишу свой собственный ContentProvider, который будет синхронизироваться с веб-службой с помощью SyncAdapter.

Проблема возникает, когда адаптер синхронизации изменяет данные провайдера контента, провайдер запускает сетевую синхронизацию при внутреннем вызове getContentResolver (). NotifyChange, вызывая цикл синхронизации.

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

Как можно, внутри контент-провайдера, легко определить, используется ли оно клиентским приложением (которое должно запускать сетьсинхронизировать при модификации) или с помощью адаптера синхронизации (который не должен запускать сетевую синхронизацию).

В настоящее время я использую различные CONTENT_URI (адаптер синхронизации обращается к данным с помощью CONTENT_URI_NO_SYNC и клиентских приложений, используя CONTENT_URI), чтобы иметь возможностьчтобы различать два типа доступа и соответственно установить флаг сетевой синхронизации.

1 Ответ

34 голосов
/ 07 июля 2011

Смотреть это видео об использовании REST API в SyncAdapter с.

Метод, который они обсуждают, заключается в добавлении набора столбцов метаданных в базу данных. Это позволяет нам делать 3 вещи.

  1. Сами флаги позволяют SyncAdapter определять строки, которые нужно изменить, и что это за изменения. Как вы определяете разницу между локально созданной строкой и локально измененной строкой? Кроме того, как узнать, какой вызов REST API сделать? Если вы просто удалите строку, как ваш SyncAdapter узнает, какую строку нужно удалить, если данные теперь пропали? Вместо этого установите флаг «Должен быть удален», а затем, когда SyncAdapter запустится, он знает, что нужно удалить удаление на сервер.

  2. Флаги позволяют CursorAdapter изменять созданное представление (например, добавляя Spinner, чтобы показать, что «эта строка синхронизируется»)

  3. Наконец, и на это они не указывают, флаги позволяют вам сказать, почему строка изменяется. Если ни один из флагов не установлен, и строка изменяется, должно из-за обновления с сервера. Поэтому нет необходимости синхронизировать с сетью.

Итак, два рабочих процесса:

Местное изменение

  1. Приложение создает новую строку. Строка "создать" флаг верна.
  2. ContentProvider сохраняет строку, видит флаг создания и поэтому вызывает notifyChange(...,true);
  3. Синхронизация с сетью = true (последний параметр) приводит к срабатыванию SyncAdapter.
  4. SyncAdapter сканирует базу данных, находит строку с установленным флагом создания и выполняет соответствующее действие сервера. После успеха SyncAdapter снимает флажок (обновление строки на ContentProvivder)
  5. ContentProvider видит, что флаг сброшен, флаги не установлены, поэтому он вызывает notifyChange (..., false);
  6. ContentObserver s, см. Флажок, обновите, чтобы он выглядел как "синхронизация завершена"

Все эти шаги эквивалентны для обновления / удаления - один флаг на синхронизируемую строку для каждого из создания / обновления / удаления. Также обратите внимание на другую победу - что, если «Создать» временно не удается? сервер не работает ... Как вы знаете, чтобы повторить попытку? - Просто, вы не снимаете флажок «Создать» и видите его через 15 минут.

Удаленная замена

  1. SyncAdapter срабатывает из-за периодической синхронизации.
  2. SyncAdapter извлекает обновление с сервера. Вносит изменения в базу данных. Не устанавливает никаких флагов. ContentProvider видит отсутствие флагов, знает, что изменение должно происходить с сервера (или это не изменение базы данных, которое необходимо отправить на сервер), поэтому оно вызывает notifyChange(...,false);
  3. ContentObserver s видят изменения содержимого, и поэтому они обновляются с новыми данными строки
...