Creating Realm Objects from JSON in Android (Using String , HashMap and JSON File)
Repository
https://github.com/realm/realm-java
What Will I Learn?
- How to create a Realm Objects and save to it using JSON File
- How to use the lambok plugin.
- How to use the RealmRecyclerViewAdapter and its subclasses.
- How to use the InputStream to read from raw files.
- How to create realm objects from Strings and HashMaps.
Requirements
- An Integrated Development Environment(IDE) for building Android Application(e.g Anroid Studio, IntelliJ)
- An Android Device or a Virtual Device.
- Java Programming Experience.
- Of course, willingness to learn
Resources
- Retrofit Website. https://realm.io/
- Retrofit Github. - https://github.com/realm
- Retrofit License - Apache License
- Lombok Project - https://projectlombok.org
Difficulty
- Intermediate
Tutorial Duration - 25 - 30Mins
Tutorial Content
Definition of Terms
JSON
In computing, JavaScript Object Notation or JSON is an open-standard file format that uses human-readable text to transmit data objects consisting of attribute–value pairs and array data types (or any other serializable value). It is a very common data format used for asynchronous browser–server communication, including as a replacement for XML in some AJAX-style systems.
Source - https://en.wikipedia.org/wiki/JSON
HashMap
A HashMap is a structure allowing one to store (key,value) items. A hash function pairs each key to an array index where the value will be stored. Android structures are composed of two arrays: ArrayMap uses a sorted array for the key hashes and the other one for the (key,value) items stored in the same order than the corresponding hash. SparseArray keeps the keys sorted in its first array and the values in the second one.
Source - https://greenspector.com/en/articles/2017-04-11-android-containers/
In todays tutorial, we are going to learn how to not only create a realm database from JSON file but also how to add realm objects from Strings and HashMaps and to illustrate this, we are going to be creating an Android application which shows a list of Song Albums using a recyclerview that will be show the Album Image, the Artist and also the year it was released.
Outline
- We add our dependencies into our gradle files.
- Include RecyclerView into MainActivity xml file.
- Create Single View for each album List.
- Create Album Model and use the Lombok Library.
- Create custom Adapter extending RealmRecyclerView.
- Create Albums JSON File.
- Create Realm from JSON File and insert realmObjects from String and HashMap.
- Link Adapter to RecyclerView in MainActivity java class file.
Dependecies used
- implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
The ButterKnife dependency should be placed in your application level gradle file - "build.gradle" which will make the injection of views (e.g ImageView, TextView) as easy as possible which we will be seeing in this tutorial.
- implementation 'org.projectlombok:lombok:1.16.20'
annotationProcessor 'org.projectlombok:lombok:1.16.20'
The lombok dependency also is placed in the application level gradle file which makes the generator of getter and setter methods for our model classes by just adding the annotations @Getter
for getters and @Setter
for the setter methods.
- implementation 'com.squareup.picasso:picasso:2.71828'
The picasso dependency is used to load images into our ImageView and should be included in our application level gradle file also.
- implementation 'io.realm:android-adapters:2.1.0'
Since we will be using the RealmRecyclerViewAdapter
instead of the usual RecyclerViewAdapter
, this plugin will have to be inserted into our application level gradle file - build.gradle
Realm dependency
Steps
Head to your project level gradle file and add the classpath dependency:
classpath "io.realm:realm-gradle-plugin:5.1.0"
Next, head to your application level Gradle file "build.gradle" and add the realm-android plugin to the top of the file.
apply plugin:'realm-android'
Finally, refresh your Gradle dependencies.
After you have added the necessary dependencies, your application level Gradle file should look like this -
and your project level Gradle file should look like this
Including a RecyclerView element to our Activity layout file.
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/albumsRecView"
>
</android.support.v7.widget.RecyclerView>
We add the following code above to include our recyclerview into our activity layout file which will be used to be displayed the list of the albums which we will be displaying by getting the results from our realm database. What we need to note here is the id of the recycler view which is albumsRecView
.
Create Single View for each album List
Inorder to display all the albums correctly, we must create a layout file that will be used to as a template to display as the album list.
Create a new layout file:
- right click on the res folder => New =>
Layout resource file
as shown in the image below.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/album_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:src="@android:drawable/alert_dark_frame" />
<TextView
android:id="@+id/album_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@id/album_img"
android:text="Album Name"
android:textSize="16sp" />
<TextView
android:id="@+id/album_year"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_below="@id/album_name"
android:layout_toRightOf="@id/album_img"
android:text="Album Year"
android:textSize="15sp" />
</RelativeLayout>
Code Explanation
The above code creates a layout as below:
The ImageView with the id - fruit_img
is placed to the right of the parent view which we will use in our adapter to display the album Pictures and then two textViews with the ids - album_name
and album_year
are used to display the albums name and year respectively.
Create Album Model
We will need to create a model class which will have both getter and setter methods for the respective fields (Name, Image, Year)which we will be needing in our recyclerview to set the details of each row.
To create the single row layout, right click on the layout folder located under the res folder, select New and then click Layout resource file
as instructed in the image below.
To reduce boilerplate code, we will be using the lombok library (https://projectlombok.org) to set the getter and setter methods of the three fields by adding the @Getter
and @Setter
annotation to the respective fields.
Your model class must extend realmObject
as shown in the code below.
@Getter
@Setter
public class Albums extends RealmObject {
String Name;
String Image;
String Year;
}
Create custom Adapter
In today's tutorial, we will not be using the normal RecyclerViewAdpater
class but the RealmRecyclerViewAdapter
which makes binding of realm objects easier.
Firstly, create a new java clas file AlbumsAdapter
and extend the RealmRecyclerViewAdapter
.
public class AlbumsAdapter extends RealmRecyclerViewAdapter<Albums, AlbumsAdapter.AlbumsViewHolder> {
public AlbumsAdapter(RealmResults<Albums> albums){
super(albums, true);
}
@Override
public AlbumsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_album_row,parent,false);
return new AlbumsViewHolder(view);
}
@Override
public void onBindViewHolder(AlbumsViewHolder holder, int position) {
final Albums albums = getItem(position);
holder.AlbumName.setText(albums.getName());
holder.albumYear.setText(albums.getYear());
Picasso.get().load(albums.getImage())
.resize(150,150)
.centerCrop()
.into(holder.albumImage);
}
class AlbumsViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.album_name)
TextView AlbumName;
@BindView(R.id.album_year)
TextView albumYear;
@BindView(R.id.album_img)
ImageView albumImage;
AlbumsViewHolder(View view){
super(view);
ButterKnife.bind(this,view);
}
}
}
Code Explanation
onCreateViewHolder()
In this method, we inflate the layout view with our single layout file - single_album_row
file with the line - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_album_row,parent,false);
and then we return the view.
onBindViewHolder()
Here, we have to set the properties of the fields of each album.
We set the details of each albums by using the setter methods gottern from our model class (albums.getName()
,albums.getYear()
,albums.getImage()
).
We use the Picasso dependency to load the image of each album and then use the resize()
method to resize it and use the centerCrop()
method to make the image display in the center of the ImageView.
The AlbumsViewHolder
class uses ButterKnife
injection to inject the views from the single_album_row
layout.
Create Albums JSON File
Next, for us to be able to create a realm database from a JSON file, we are going to have to create a json file which will have four(4) objects that will represent four rows of album details.
To do that, right click on your res folder, click on New => Android Resource Repository, from the Resource type drop down, select raw and then click okay.
NB: See Image for more details.
Next, click on the newly created raw folder => New => File and name the file albums.json
.
In this file, we will have four json objects inside an array, and this objects will have three fields - Name
, Image
and Year
.
[
{
"Name": "Revival",
"Year": "2017",
"Image": "https://upload.wikimedia.org/wikipedia/en/thumb/8/86/Revival_by_Eminem_cover.jpg/220px-Revival_by_Eminem_cover.jpg"
},
{
"Name": "Gravity",
"Year": "2012",
"Image": "https://upload.wikimedia.org/wikipedia/en/thumb/7/7a/Gravity_%28Lecrae_album%29.jpg/220px-Gravity_%28Lecrae_album%29.jpg"
},
{
"Name": "Royalty",
"Year": "2015",
"Image": "https://cdn.smehost.net/chrisbrownworldcom-usrcaprod/wp-content/uploads/2015/11/CB-Royalty-300EX.jpg"
},
{
"Name": "Loud",
"Year": "2010",
"Image": "https://upload.wikimedia.org/wikipedia/en/thumb/d/d1/Rihanna_-_Loud.png/220px-Rihanna_-_Loud.png"
}
]
Create Realm from JSON File
Next, we head over to our MainActivity.java
class file, create a Realm variable - private Realm realm;
.
In the onCreate()
method, we have to initialize realm and also get a realm instance :
Realm.init(this);
realm = Realm.getDefaultInstance();
We then call a method - fillUpDatabase()
that will be responsible for creating the database and also using an InputStream
to populate the realm database with the json objects in our albums.json
file.
Create Realm from JSON File and insert realmObjects from String and HashMap
fillUpDatabase()
private void fillUpDatabase() {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
InputStream inputStream = getResources().openRawResource(R.raw.albums);
try {
realm.createAllFromJson(Albums.class,inputStream);
} catch (IOException e) {
if (realm.isInTransaction())
realm.cancelTransaction();
}
}
});
}
We execute a realm transaction on the realm variable by calling the executeTransaction()
method and override the execute()
method.
We use an InputStream object - inputStream
to get the json file resource by calling the getResources()
method and then calling the openRawResource()
method with the albums
json file as an argument.
realm.createAllFromJson(Albums.class,inputStream);
creates a realm database of Albums
class and gets its values from the inputStream
.
createRealmObjectFromString()
The next method call is the createRealmObjectFromString()
which creates a realm object from a String.
private void createRealmObjectFromString() {
final String json = "{ Name: \"Pink Friday\", Image: \"https://upload.wikimedia.org/wikipedia/en/thumb/f/f1/Pink_Friday_album_cover.jpg/220px-Pink_Friday_album_cover.jpg\" ,Year: 2010}";
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.createObjectFromJson(Albums.class, json);
}
});
}
We declear a final String variable called json
which has the format of a json object (e.g {}), we set the Name, Image and Year of the album in the string variable and then execute a transaction on the realm variable realm.executeTransaction()
and then we then create a realm object of the Albums
class with the json
String variable as the second type with the line realm.createObjectFromJson(Albums.class, json);
.
createRealmObjectFromHashMap()
private void createRealmObjectFromHashMap() {
Map<String, String> album = new HashMap<String, String>();
album.put("Name", "Love Letter");
album.put("Image", "https://images-na.ssl-images-amazon.com/images/I/71sbfQ0L9bL._SY355_.jpg");
album.put("Year", "2010");
final JSONObject json = new JSONObject(album);
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.createObjectFromJson(Albums.class, json);
}
});
}
In this method, we create a new Map object and indicate that it's of type <String, String>
.
Next, we use the put method to insert key-value pairs of an album object, we then create a new JSONObject variable with the album map - final JSONObject json = new JSONObject(album);
.
Lastly, we execute a transaction on our realm variable and then create a realm object with the Album
class and the json object - json
as the second argument - realm.createObjectFromJson(Albums.class, json);
Link Adapter to RecyclerView in MainActivity java class file
Next, we need to get all the objects in the Album
realm database and then set it as an argument for our adapter and also set the adapter for our recycler view and lastly include a layout manager for the recyclerview.
We have to inject the recyclerview in our activity_main
layout file by placing our cursor on the layout file name located on this line - `setContentView(R.layout.activity_main);' => alt + ins => Generate ButterKnife Injection, then check the check box to the left of our recycler view view.
NB: See Image for Steps.
We then have to use begin a realm transaction to get the objects of the Albums
class, store it in a RealmResults
variable - results
and then finally commit the transaction -
realm.beginTransaction();
final RealmResults<Albums> results = realm.where(Albums.class).findAll();
realm.commitTransaction();
Finally, we have to set a vertical LinearLayoutManager
as the layoutManager of the recyclerView - albumsRecView
,
we set the recyclerview to have a fixed size - albumsRecView.setHasFixedSize(true);
and we set the Adapter of the recyclerview by calling the setAdapter()
method and passing the resuls variable which now holds all the realm objects of type Albums
- albumsRecView.setAdapter(new AlbumsAdapter(results));
albumsRecView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
albumsRecView.setHasFixedSize(true);
albumsRecView.setAdapter(new AlbumsAdapter(results));
Complete MainActivity.java class
public class MainActivity extends AppCompatActivity {
@BindView(R.id.fruitsRecView)
RecyclerView fruitsRecView;
private Realm realm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
Realm.init(this);
Realm.deleteRealm(Realm.getDefaultConfiguration());
realm = Realm.getDefaultInstance();
fillUpDatabase();
createRealmObjectFromString();
createRealmObjectFromHashMap();
realm.beginTransaction();
final RealmResults<Albums> results = realm.where(Albums.class).findAll();
realm.commitTransaction();
fruitsRecView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
fruitsRecView.setHasFixedSize(true);
fruitsRecView.setAdapter(new AlbumsAdapter(results));
}
private void createRealmObjectFromHashMap() {
Map<String, String> album = new HashMap<String, String>();
album.put("Name", "Love Letter");
album.put("Image", "https://images-na.ssl-images-amazon.com/images/I/71sbfQ0L9bL._SY355_.jpg");
album.put("Year", "2010");
final JSONObject json = new JSONObject(album);
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.createObjectFromJson(Albums.class, json);
}
});
}
private void createRealmObjectFromString() {
final String json = "{ Name: \"Pink Friday\", Image: \"https://upload.wikimedia.org/wikipedia/en/thumb/f/f1/Pink_Friday_album_cover.jpg/220px-Pink_Friday_album_cover.jpg\" ,Year: 2010}";
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.createObjectFromJson(Albums.class, json);
}
});
}
private void fillUpDatabase() {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
InputStream inputStream = getResources().openRawResource(R.raw.albums);
try {
realm.createAllFromJson(Albums.class,inputStream);
} catch (IOException e) {
if (realm.isInTransaction())
realm.cancelTransaction();
}
}
});
}
}
In order for this application to fully work, we must include the <uses-permission android:name="android.permission.INTERNET"></uses-permission>
permission in the Manifest file .
Application Execution
Tutorial codes can be gotten from this GitHub repository: https://github.com/generalkolo/Realm-JSON
Proof of Work
https://github.com/generalkolo
Thank you for your contribution.
While I liked the content of your contribution, I would still like to extend few advices for your upcoming contributions:
Looking forward to your upcoming tutorials.
Your contribution has been evaluated according to Utopian rules and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post,Click here
Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
Thanks @portugalcoin I would definitely improve on my subsequent contributions.
Thanks for taking out time to moderate my contribution.
Hey @edetebenezer
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Contributing on Utopian
Learn how to contribute on our website or by watching this tutorial on Youtube.
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
Hi @edetebenezer I am new here you know every one can want to be learn and earn from Steemit so how can we earn when we doing work like friends sporting each other like up voting commenting etc then we will enjoy Steemit if you agree reply back n .vote for vote