Использование Retrofit с ActiveAndroid

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Ваш комментарий будет опубликован после модерации