Как реализовать простую архитектуру REST и ContentProvider с использованием моделей?
В настоящее время я разрабатываю приложение для Android, которое взаимодействует с веб-сервисом RESTful. Клиент может выполнять полный CRUD на веб-сервисе. После поиска лучших практик я просмотрел ключевую информацию Google I/O 2010 о клиентах REST, которая цитируется почти во всех статьях.
Чтобы использовать как можно большую часть платформы Android, я решил использовать вариант B с помощью ContentProvider
и SyncAdapter
. Это обеспечило мне встроенную систему учетных записей, наблюдателей контента и периодическую синхронизацию при доступе к Интернету.
Поскольку одна очень важная функция нашего приложения - это автономное редактирование и доступность (он используется в средах с плохим приемом), мы хотим сохранить как можно больше релевантных данных на локальном уровне.
Клиент связывается с сервером с помощью RESTful API в Json, данные с сервера десериализуются с помощью Gson на Модели (POJO, обычные Java-объекты).
Чтобы код был чистым и легким для чтения, я попытался создать собственный объект mapper вместо прямого использования Cursor
. Этот модуль отображает стандартные CRUD-операции и карты Курсоры до Модели при чтении данных и Модели до ContentValues при записи данных.
Однако эта архитектура выглядит очень раздутой.
-
В первую очередь невозможно получить достоверную информацию о текущем SyncState
(чтобы обеспечить обратную связь с пользователем). (Теперь "взломан" с помощью этого SO-ответа)
-
Вторая проблема заключается в том, что для каждого ресурса мне понадобится: Модель, сопоставление, определение таблицы и URI ContentProvider. Который много кода управляет только одним ресурсом.
-
Третья проблема заключается в том, что, требуя моделей через мой обработчик, я заблокировал себя от использования CursorLoader
в действиях.
Нижняя строка
Я ищу поддерживаемый и легкий способ иметь автономный контент и синхронизацию с веб-сервисом RESTful с помощью Json. Также я хотел бы иметь возможность использовать Модели в моем коде, потому что user.getName()
гораздо более дружественный для разработчиков, чем cursor.getString(cursor.getColumnIndex(UserDataSource.COLUMN_NAME));
(который сейчас скрыт в моем классе Mapper).
Хорошим примером для сопоставления будет Dapper в сочетании с Расширения Dapper, написанные для .NET, но похожие на мой подход, однако мой подход потребовал, чтобы все столбцы и поля были определены во многих разных файлах (см. Выше).
Кроме того, я собираюсь отказаться от ContentProvider
из моего кода, потому что он чувствует себя очень раздутым и устаревшим для такой простой задачи.
Ответы
Ответ 1
Рассматривали ли вы использование ORM? У меня был успех с комбинацией OrmLite и Jackson в прошлом. Вам нужно будет написать свой собственный сервис для синхронизации, но OrmLite позаботится о тяжелом подъеме, когда дело доходит до ваших моделей данных.
Хотя вы не получите некоторые из тонкостей, которые предоставляет комбинация ContentProvider + SyncAdapter (до сих пор нет CursorLoader при использовании POJO), эта настройка может облегчить нагрузку на сложную схему и/или множество типов.
Вот пример определения таблицы с домашней страницы OrmLite:
@DatabaseTable(tableName = "accounts")
public class Account {
@DatabaseField(id = true)
private String name;
@DatabaseField(canBeNull = false)
private String password;
}
Как вы можете видеть, определение модели + сопоставление + таблица происходит очень быстро и безболезненно.