Realm for Android and initial seed data: Pre-populating from Json and extracting the database

Written by chron.vas | Published 2016/08/01
Tech Story Tags: realm | android | json | database

TLDRvia the TL;DR App

I’ve came across the “hustle” of creating an app that will use Realm, having the database previously populated with data and just include the created database file in the published app, omitting the Json (or any other file) that is being used to populate it.

Doing so for a “to be published” app saves time (parsing the file and populating a db) and space (omitting the file which used to create the database).

The main idea:

I’m going to show the simplest possible way to achieve this, but this can be much improved (a separate Gradle task maybe?) and even be a part of the main project, not having to maintain 2 code bases and 2 different projects for one app.

For the hasty

The project is on Github, but check the “Keep in mind” section first

Begin!

I am using Android Studio (3.1) and Realm Java version 5.0.0.The build.gradle of the project looks like this:

And the build.gradle of the app module looks like this:

It’s time to add a class that extends android.app.Application, so our whole application starts from this class and Realm gets initialized and configured on OnCreate. It’s handy to set a name for your .realm file containing the database. More configurations can be passed in this way. Just remember to point out this class in the Android Manifest.

Now we need the Json file. A simple one for brevity reasons named “people.json” :

The .json file has to be placed into raw resources in order to be accessible. Create the raw resource folder if it does not exist

The representing Java class for parsing the Json:

Ok! It’s time for parsing

Normally, we would use a helper class extending AsyncTask. But thanks to the Realm.executeTransaction we can just this built in method instead.

And a simple button to call .importFromJson()

Keep in mind that calling importFromJson does not delete the database or the data in it, it just adds the results from the Json parsing.

On Android monitor we can view the time it took to complete, and possibly saved from a published app.

Now, where is my .realm database file?

Once you run the application to a device, in Android Studio, open “Device File Explorer”, navigate under the “ Data / Data / <Package Name> / files ” directory you can find the .realm file and pull it to your computer.

Did it work?

You can add another button for simplicity to return the number of Persons found in the database. The code of the two simple buttons could look like this:

Now just take the .realm file and place it under raw resources again to be used as the database.

On the “to be published” app

Just put the .realm file in the raw resource directory and copy it to the appropriate place (FilesDir) using copyBundledRealmFile method on App.java .

I added an shouldOverwriteDatabaseOnAppStartup flag if you want to overwrite the database every time the app starts with a fresh one, or just keep the one that copyBundledRealmFile created the first time the app ran:

Keep in mind!

  • With the shouldOverwriteDatabaseOnAppStartup flag set to true, every time your application starts, it copies or overwrites the .realm database from raw directory to the /files directory, so keep in mind that whatever change you make it is going to be lost upon App.java call. In order to demonstrate the “problem” I have added 2 more buttons to change and query the name of the first person. In order to avoid this, set the flag to false, which makes a file existence check before writing the .realm file.
  • The .realm file still has 2 instances. In the raw resource directory and in the /files directory. So saving space is not done in fully.
  • Don’t forget to use the correct data model when you read the database, or a realm migration if needed.

I hope you found this article useful. The project can be found here https://github.com/chronvas/RealmTesting

Special thanks to Kenneth Geisshirt for reading this and suggesting realm.executeTransaction over AsyncTask


Published by HackerNoon on 2016/08/01