Using Retrofit with ActiveAndroid
In a previous article I talked about a smart way to use Retrofit library. This is a great library but recently I had to manage offline data and I thought ‘Hey, it would be great to download data and save it into a database to create some sort of cache :)’. I found a lot of ORM library such as GreenDAO, OrmLite, SugarORM and ActiveAndroid. I wanted a simple and powerful library. I’ve chosen ActiveAndroid library and I will explain how to use it with Retrofit.
Don’t worry, you don’t need to be a Senseï in SQLite to understand this article (I’m not ;). You just need to know what is a DataBase, a model and the definition of a foreign key. I will explain each of these points at the right moment so don’t panic, it will be easy and fast to use and to enjoy ;).
What do you need ?
First of all you will need to add a Gradle dependencie and next you will have to add some lines to the Manifest and the Application class.
Gradle
ActiveAndroid is not on GradlePlease so you will have to add the Snapshots repository to the build.gradle
.
1 2 3 |
|
Now you can fetch it like others Gradle libraries by adding this line in Gradle dependencies.
1 2 3 |
|
If you synchronize project with Gradle files, everything should be ok :).
Manifest and Application class
You will need to update the manifest to define the name and the version of the SQLite database. You also need to use ActiveAndroid Application class to start using this library.
Application Class
If you don’t have already created a custom Application class, you have to create a new class that extends from com.activeandroid.app.Application
1 2 3 4 5 6 7 8 |
|
Or if you have already a class that extends from Application or whatever you have to call the initialize
method from ActiveAndroid in the onCreate method.
1 2 3 4 5 6 7 8 9 10 11 |
|
Manifest
If you want that your application use the custom application, you have to add it in the Manifest
. Moreover you have to set the name and the version of your database. The version is used to update the database tables without having to uninstall the application.
1 2 3 4 5 6 7 8 9 10 11 |
|
Models
The ActiveAndroid ORM is a Code-First
ORM. This means that your POJOs are used to create tables in the Database. With annotations above classes and fields, you can set the name of tables and the name of the columns.
Books
This is an example that show how to use ActiveAndroid with a simple POJO.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Pages
In a book there are pages, so let’s go create a Page POJO. In this example we need to associate each page to a book it’s a many-to-one relation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
With the book object, the library create a foreign key that is the id of the page book. The onDelete is optional, it means that if we delete a book, the pages with its foreign key will be deleted too. Next we have to add two lines to the Book class to retrieve these pages.
1 2 3 4 |
|
Optimization
Now that you know how to create a Model with ActiveAndroid, you can optimize a little bit the creation and the search process of this library by adding in the manifest the list of models. This way the library will not have to search in all your classes to find which one extends from Model. Just below the database name and version, you have to add the list of Model separated by a coma.
1 2 3 |
|
What about Retrofit ?
The purpose of this article is to explain how to combine Retrofit and ActiveAndroid. You can use ActiveAndroid in the generic callback of Retrofit or create a custom callback class to manage it.
In both cases you have to add some changes to the gson object in the RestClient class
created in the previous article about Retrofit.
To avoid issue when serialization and deserialization of POJOs you have to add the @Expose
annotation above fields and exclude serialization of fields without Expose annotation by calling excludeFieldsWithoutExposeAnnotation()
method on the Gson object. For example Page class will look like this :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
You have to do the same thing to expose fields from Book class. Now that we have all classes to make it works, take a look at this JSON example that will be used with Retrofit callback.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
|
With this JSON you can expect to receive, in the Retrofit callback, a List of Books. Until here it’s the same thing that I’ve explained in the Retrofit article. But here, POJOs extends from Model so the difference is that you can save it into database, you just have to call save()
method on each item of the received list.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Now, you have saved all pages and books into database. You can try to fetch books and pages without network. As I said previously, you can also create a custom callback class and manage all this stuff in it.
Warning
When I used this combination for the first time, I had several issues and I wanted to warn you about it. There are two main points, the ActiveAndroid cache and the save function.
Cache Request
ActiveAndroid library has a cache system. If you have some fields in POJOs that do not exist in SQLite database then you each time you will fetch data from database the same object will be retrieved. So be careful when you are using POJOs with potentially persistent fields. If you don’t want to use the ActiveAndroid cache you can clear it by calling the static method clearCache()
.
1
|
|
Save trap
When you instantiate a new Model, it’s not saved until you call save()
and if you save an object, the children like pages of book are not saved. To create the foreign key and save child objects you have to set book reference and next call save method on page. But this will work only if book parent is previously saved because ActiveAndroid library needs an _id
to create the foreign key.