Creating Realm Objects from JSON in Android (Using String , HashMap and JSON File)

in #utopian-io6 years ago (edited)

realmDark.jpg

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

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 -

application Level Gradle 1.PNG
application Level Gradle 2.PNG

and your project level Gradle file should look like this

application level gradle file.PNG

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.

new Layout.PNG

<?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:

Single View

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.

raw folder creation.PNG

raw folder naming.PNG

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.

Butterknife Injection 3.PNG

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

Application Execution

Tutorial codes can be gotten from this GitHub repository: https://github.com/generalkolo/Realm-JSON

Proof of Work

https://github.com/generalkolo

Related Videos

Sort:  

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:

  • In the images where you have code, put the most visible code. In your images it's difficult to see the code.
  • There are parts of the code that have little explanation, try to explain as much as possible.
  • Put your curriculum at the end of the tutorial.

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

Coin Marketplace

STEEM 0.18
TRX 0.14
JST 0.029
BTC 58132.39
ETH 3138.08
USDT 1.00
SBD 2.44