Как реализовать простую архитектуру 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;   
}

Как вы можете видеть, определение модели + сопоставление + таблица происходит очень быстро и безболезненно.