В прошлой статье я рассказывал об использовании 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.
