В прошлой статье я рассказывал об использовании Retrofit. Это отличная библиотека, но недавно мне пришлось работать с оффлайн данными и я подумал: «Было бы здорово загружать данные и сохранять его в базе данных, сделав что-то вроде кэша». Я нашел много ORM-библиотек, таких как GreenDAO, OrmLite, SugarORM и ActiveAndroid. Я хотел простую и мощную библиотеку. Я выбрал библиотеку ActiveAndroid и я объясню, как использовать его в связке с Retrofit.
Что вам нужно?
Для начала нам нужно добавить зависимости в Gradle и несколько строк в Manifest-файл.
Gradle
Добавим репозиторий Snapshots в build.gradle:
repositories { maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } }
Теперь мы можем подключить ActiveAndroid как обычную библиотеку, добавив следующую зависимость:
dependencies { compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT' }
Класс Application
Если вы еще не создали пользовательский класс Application, вы должны создать новый класс, который наследуется от com.activeandroid.app.Application:
public class App extends com.activeandroid.app.Application { @Override public void onCreate() { super.onCreate(); } }
А ваш Application уже наследуется от другого класса, то инициализируйте AndroidActive, вызвав метод init в onCreate вашего приложения:
public class App extends SomeOtherApplication { @Override public void onCreate() { super.onCreate(); ActiveAndroid.initialize(this); } }
Манифест
Если вы хотите, чтобы ваше приложение использовало пользовательский класс Application, нужно прописать его в AndoidManifest.xml. Кроме этого нужно прописать имя и версию базы данных. Версия нужна для обновления базы без удаления приложения:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application … android:name="CustomApplication"> <meta-data android:name="AA_DB_NAME" android:value="yourDatabase.db"> <meta-data android:name="AA_DB_VERSION" android:value="1"> </application> </manifest>
Модели
В качестве примера я буду использовать модель книг. Для работы ActiveAndroid используются аннотации:
import com.activeandroid.Model; import com.activeandroid.annotation.Column; import com.activeandroid.annotation.Table; // Наша таблица будет называться "Books" @Table(name = "Books") public class Book extends Model { // Эта аннотация, означает, что в таблице есть столбец "Author" @Column(name = "Author") public String author; @Column(name = "Title") public String title; @Column(name = "Description") public String description; public List<Page> pageList; public Book() { super(); } }
Страницы
У книг есть страницы, поэтому давайте создадим класс Page. Нам нужно связать страницы с книгами, это отношение один ко многим:
import com.activeandroid.Model ; import com.activeandroid.annotation.Column ; import com.activeandroid.annotation.Table ; @Table ( name = "Pages" ) public class Page extends Model { @Column ( name = "Number" ) public Integer number ; @Column ( name = "Text" ) public String text ; @Column ( name = "Chapter" ) public String chapter ; @Column ( name = "Book" , onDelete = Column.ForeignKeyAction.CASCADE) public Book book ; public Page () { super (); } }
Над объектом book в аннотации мы приписали onDelete = Column.ForeignKeyAction.CASCADE
. Это значит, что удалении книги удалятся и страницы, связанные с этой книгой.
Добавим метод для получения списка страниц в класс Book:
public List<Page> getPageList() { return getMany(Page.class, "Book"); }
Оптимизация
Теперь, когда вы знаете, как создавать модели в ActiveAndroid, вы можете немного оптимизировать работу библиотеки, добавив в манифесте список моделей. Таким образом библиотеке не придется искать модели во всех классах. Чуть ниже имени базы данных и версии, вы должны добавить список моделей, разделенные запятыми.
<meta-data android:name="AA_MODELS" android:value="com.example.Book, com.example.Page">
Что такое Retrofit?
Цель этой статьи объяснить, как связать Retrofit с ActiveAndroid. Чтобы избежать проблем с сериализацией наших объектов мы должны настроить наш RestClient.
Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create(); RestAdapter restAdapter = new RestAdapter.Builder() .setConverter(new GsonConverter(gson)) .build();
Метод excludeFieldsWithoutExposeAnnotation() означает, что поля не аннотированные аннотацией @Expose не будут сериализованы.
Вот как теперь выглядит наша модель:
import com.activeandroid.Model ; import com.activeandroid.annotation.Column ; import com.activeandroid.annotation.Table ; @Table ( name = "Pages" ) public class Page extends Model { @Expose @Column ( name = "Number" ) public Integer number ; @Expose @Column ( name = "Text" ) public String text ; @Expose @Column ( name = "Chapter" ) public String chapter ; @Column ( name = "Book" , onDelete = Column . ForeignKeyAction . CASCADE ) public Book book ; public Page () { super (); } }
Также поступаем с классом Book:
import com.activeandroid.Model; import com.activeandroid.annotation.Column; import com.activeandroid.annotation.Table; @Table(name = "Books") public class Book extends Model { @Expose @Column(name = "Author") public String author; @Expose @Column(name = "Title") public String title; @Expose @Column(name = "Description") public String description; public List<Page> pageList; public Book() { super(); } }
А вот так выглядит наш JSON:
[ { "author": "John Smith", "title": "Android World", "description": "Lorem ipsum", "pages": [ { "number": 1, "text": "Lorem ipsum", "chapter": 1 }, { "number": 2, "text": "Lorem ipsum", "chapter": 1 }, { "number": 3, "text": "Lorem ipsum", "chapter": 1 } ] }, { "author": "John Smith", "title": "Android World II", "description": "Lorem ipsum Lorem ipsum", "pages": [ { "number": 1, "text": "Lorem ipsum Lorem ipsum", "chapter": 1 }, { "number": 2, "text": "Lorem ipsum Lorem ipsum", "chapter": 1 }, { "number": 3, "text": "Lorem ipsum Lorem ipsum", "chapter": 1 } ] } ]
Retrofit будет автоматически создавать объекты книг со страницами. Для того, чтобы сохранить книги в БД мы просто должны вызвать метод save():
final Callback<List<Book>> bookCallback = new Callback<List<Book>>() { @Override public void success(List<Book> books, Response response) { for (Book book : books) { book.save(); for (Page page : book.pageList) { page.book = book; page.save(); } } } @Override public void failure(RetrofitError error) { } };
Теперь, мы сохранили все страницы и книги в базе данных. Вы можете попробовать, загрузить книги и страницы без сети.
Источник: Using Retrofit with ActiveAndroid.