JavaScript Object Notation (JSON) is a popular text file format used in many applications including in Android app development.
In this Android JSON tutorial post I will cover how to perform common tasks using the JSON file format in Android app development including:
- How to Parse a JSON String in Android
- How to Generate a JSON Object in Android
- How to Parse a JSON File from a URL or API using Volley
- How to Parse a JSON File from a URL or API using Retrofit
- How to Convert a JSON String into a Java Object in Android
- How to Convert a Java Object into a JSON String in Android
- How to Create a JSON File in Android
I have include code samples within this post and all the code from this tutorial is also available in the following public GitHub repository I created at the following link.
https://github.com/learntodroid/AndroidJSONTutorial
Please read on to get started on the JSON tutorial for Android.
What is JSON used for in Android development?
JSON (JavaScript Object Notation) is a text based file format that is used for sharing data between applications in a standard format supported by most programming languages and platforms. In addition to being programming language and platform independent JSON is also human readable.
See a sample JSON file below.
A JSON file is made up of a JSON object enclosed in curly brackets “{” and “}” and consists of attribute name and value pairs. Attribute names are Strings enclosed in double quotation marks and are associated to a value with a colon “:” in between. Values can be of different formats such as a number, String, boolean, array, a nested JSON object or null. Attribute and value pairs are comma “,” separated.
In Android app development it is common to use JSON in the following scenarios:
- Saving and loading data
- Retrieving data from a location on the Internet
- Integrating with an API or a web service and sending and receiving data
JSON Parsing in Android
What is JSON Parsing in Android?
In the context of Android app development JSON parsing means taking a String representation of JSON and transforming it into a JSON object that allows us to interpret the data within the JSON file and use it in our application.
There are a four classes offered to us in the Android org.json package that enable us to parse JSON files.
How to Parse a JSON String in Android using JSONObject
JSONObject and JSONArray Methods for JSON Parsing in Android
Parsing a JSON String can be achieved in Android using the JSONObject class in the org.json package.
To parse a JSON String using the JSONObject create a new JSONObject and pass the JSON String as a parameter to the constructor. From there you are able to access various JSON attribute values using the following methods from the JSONObject class.
Method | Description |
---|---|
boolean getBoolean(String) | Retrieve a boolean value in the JSONObject for the attribute corresponding to the key passed. If this is not possible throw a JSONException. |
double getDouble(String) | Retrieve a double value in the JSONObject for the attribute corresponding to the key passed. If this is not possible throw a JSONException. |
int getInt(String) | Retrieve an int value in the JSONObject for the attribute corresponding to the key passed. If this is not possible throw a JSONException. |
long getLong(String) | Retrieve a long value in the JSONObject for the attribute corresponding to the key passed. If this is not possible throw a JSONException. |
String getString(String) | Retrieve a String value in the JSONObject for the attribute corresponding to the key passed. If this is not possible throw a JSONException. |
JSONObject getJSONObject(String) | Retrieve a JSONObject value in the JSONObject for the attribute corresponding to the key passed. If this is not possible throw a JSONException. |
JSONArray getJSONArray(String) | Retrieve a JSONArray value in the JSONObject for the attribute corresponding to the key passed. If this is not possible throw a JSONException. |
If your JSON String contains a JSON Array inside it, use the following methods from the JSONArray class in the org.json package documented in the table below to access data within the JSONArray.
Method | Description |
---|---|
boolean getBoolean(int) | Retrieve a boolean value from the JSONArray at the index passed as a parameter. If this is not possible throw a JSONException. |
double getDouble(int) | Retrieve a double value from the JSONArray at the index passed as a parameter. If this is not possible throw a JSONException. |
int getInt(int) | Retrieve a int value from the JSONArray at the index passed as a parameter. If this is not possible throw a JSONException. |
long getLong(int) | Retrieve a long value from the JSONArray at the index passed as a parameter. If this is not possible throw a JSONException. |
String getString(int) | Retrieve a String value from the JSONArray at the index passed as a parameter. If this is not possible throw a JSONException. |
JSONObject getJSONObject(int) | Retrieve a JSONObject value from the JSONArray at the index passed as a parameter. If this is not possible throw a JSONException. |
JSONArray getJSONArray(int) | Retrieve a JSONArray value from the JSONArray at the index passed as a parameter. If this is not possible throw a JSONException. |
JSON Parsing Example in Android
In this section of the tutorial I will show you how to parse a JSON String in Android through an example of a dating app where we will be retrieving details from a JSON string to display in the dating profile.
See the screenshot below of what we will be building.
First we will need to create a layout resource for the dating profile fragment. Have a look at my layout resource below which contains the following.
- Two ImageViews, one for the profile picture and another for the background image
- Three EditTexts and TextViews (used as a label for the EditText) for capturing the Name, Age and Hobbies to show on the dating profile
- Two Buttons to load the dating profile and save the dating profile
In this part of the tutorial we will only focus on the loading dating profile details from the JSON file.
See the code sample for the ProfileFragment class that contains the loadProfile() method used for loading the details of the dating profile from a JSON file into fragment.
In the onCreateView(…) method the loadProfile() method is invoked.
In this app we will be using Shared Preferences for storing the dating profile JSON String. Before we have saved our first profile the key value pair in the shared perferences for the dating profile JSON String will be empty so we will want to use a default value for the JSON String in this instance. That is why at the top of the loadProfile() method a JSON String is defined is to be used as a default JSON String value.
Next in the loadProfile() method we retrieve the JSON String for the dating profile from shared preferences and if value has not been defined in the shared preferences we will use the default JSON String.
After this in the loadProfile() method we will use the JSONObject class to parse the JSON String to access the data we need from the JSON String to populate details in the dating profile. To parse the JSON String using the JSONObject class we will pass the JSON String as a parameter to the JSONObject constructor.
The name of the person in the dating profile is retrieved using the getString(String) method on the JSONObject passing the attribute “name” as a parameter to the getString(String) method. The String value containing the name will be set in the relevant EditText.
The age of the person in the dating profile is retrieved using the getInt(String) method on the JSONObject passing the attribute “age” as a parameter to the getInt(String) method. The value of the age will be converted into a String will be set in the relevant EditText.
To get the list of hobbies to show in the dating profile we using the getJSONArray(String) method on the JSONObject passing the attribute “hobbies” as a parameter to the getJSONArray(String) method. We use the get(int) method on the JSONArray containing all of the hobbies and loop through each hobby in the JSONArray passing an integer as an index to the array and add each hobby to a list of Strings. Once we have a list of Strings for the hobbies we transform them into a single comma seperated value to be shown inside the EditText.
To get the two images for the profile image and the background image we retrieve the a nested JSONObject containing the URIs to the two images using getJSONObject(String) method on the JSONObject passing the attribute “images” as a parameter to the getJSONObject(String) method. Then we will chain the getString(String) method and pass “background_image_uri” for the background image or pass “profile_image_uri” for the profile image.
Once we obtain the URI to the images we will use the Glide library to load the images into the ImageViews. Because we will be retrieving images from the Internet using Glide you will also need to ensure you have added the Internet permission to your app manifest file.
To learn about Glide and how to set it up and use it for loading images from the web check out the article I wrote below.
The ProfileFragment is set up inside the MainActivty using the Jetpack Navigation Component. For the rest of the code for setting up the fragment in the activity check out the code available in the GitHub repository.
To learn more about using the Jetpack Navigation Component with bottom navigation have a look at this tutorial I wrote linked below.
How to Generate a JSON Object in Android
The JSONObject class available in Android also contains some methods that allow you to create or modify a JSON object and then output it in the JSON String format.
See the code sample for the saveProfile() method below used in the dating profile fragment for updating a JSON object representing a profile and then saving the result in a JSON String format inside SharedPreferences.
In the first section of this method we will set up SharedPreferences to allow us to write data using the SharedPreferences editor.
Then we will create a new JSON object using the JSONObject constructor with no parameters. Now that the JSONObject has been created we will use the various put(…) methods on the JSONObject class to add attributes with values to the JSON Object.
To add the name attribute with the name value provided in the dating profile we use the put(String, String) method on the JSONObject with the first parameter representing the name of the attribute i.e. “name” and the second parameter representing the value for the “name” attribute.
To add the age attribute and value we use the put(String, int) method on the JSONObject with the first parameter representing the name of the attribute “age” and the second parameter representing the int value of the age specified in the dating profile.
We will allow use the put(String, JSONArray) method to add the list of hobbies in the dating profile to the JSONObject. First we need to create a JSONArray and add each hobby to the JSONArray using the put(String) method on the JSONArray object. Then we use the put(String, JSONArray) method on the JSONObject and set the attribute name as “hobbies” for the first parameter and provide the JSONArray containing an array of Strings representing the hobbies as the second parameter.
The JSONObject class also supports to ability to add nested JSONObjects using the put(String, JSONObject) method. We will use this when populating the two URIs for the background and profile images into the JSONObject. First we will create a new JSONObject and populate the two URIs as seperate attribute values onto that JSONObject. After that we will add this new JSONObject containing the two image URIs to the existing JSONObject using the put(String, JSONObject) method setting the attribute name as “images” for the first parameter and the new JSONObject as the second parameter.
After that we convert the JSONObject into it’s JSON String representation using the toString() method on the JSONObject. We then take this JSON String and save it to SharedPreferences using the putString(…) and commit() methods.
How to Parse a JSON File from a URL
In this section of the tutorial I will cover how to use the libraries Volley and Retrofit to parse a JSON file from a URL.
Parsing a JSON File from a URL or API Using Volley
In this section of the tutorial I will show you how to use the Volley library from Google for parsing a JSON file from a URL.
Will we will creating an Android app that retrieves posts from the popular social media platform reddit.com for a given subreddit and parse the JSON file retrieved from the Internet to show as a list of posts in the app.
First we will need to add some dependencies to our app level build.gradle file including Volley, RecyclerView and CardView. See the sample build.gradle file below containing each of these implementation dependencies.
Because we will be using the Internet to retrieve the JSON data containing the Posts from Reddit make sure you add permission to use the Internet in your Android manifest file.
Next we will create a class to represent a Reddit Post which will contain fields that we want to display in the user interface.
To get an idea what the JSON response will look like, pick a subreddit and go to the following URL in your browser replacing the subreddit name with a real subreddit.
- https://www.reddit.com/r/<subreddit>.json
Examples of the JSON URIs for the popular subreddits include:
- https://www.reddit.com/r/AskReddit.json
- https://www.reddit.com/r/news.json
- https://www.reddit.com/r/videos.json
You should see the JSON file look something like this in your browser which contains posts corresponding to the subreddit you selected in your URL.
To make it easier to read the JSON output, copy and paste the JSON String from the web browser into a JSON formatter tool available online such as jsonformatter.curiousconcept.com or jsonformatter.org
The fields we will want to show from a Reddit Post are the title, the current score and the comment count. See the code sample for the Post class below.
Next given that we will be showing the list of Reddit Posts from a subreddit inside a RecyclerView we will need to create a RecyclerViewAdapter for our posts.
We will start this by creating the layout resource to use for each item to be shown in the RecyclerView for the Reddit Posts. See the sample layout resource below as an example.
Next we will create the RecyclerViewAdapter for the list of Posts to be shown in the RecyclerView. This will also involve creating a RecyclerViewHolder for showing each Post in the RecyclerView.
Check out the code sample below for the PostRecyclerViewAdapter and the PostViewHolder.
Next we will create a class for to be used for making HTTP requests using the Volley library. Have a look at the code sample for the MyRequestQueue class below.
After this we will set up our new fragment to capture the subreddit and display the results containing the Posts by creating the layout resource for this new fragment.
This fragment will contain:
- An EditText for capturing the subreddit name
- A Button with the label “Get Posts” to trigger the downloading of the JSON file from the Internet and parsing the results to show in the RecyclerView
- A RecyclerView to show the Posts retrieved from a given subreddit
See the layout resource for the subreddit fragment below.
Next we will be creating the SubredditFragment class we which contain code for retrieving the subreddit entered by the user into the EditText, making a HTTP request to retrieve the JSON file using Volley then parsing the JSON response and displaying the Posts in the RecyclerView.
See the code sample for the SubredditFragment class below.
In the onCreateView(…) method in the SubredditFragment we inflate the layout resource we created above for the SubredditFragment and find the Views for the subreddit EditText, get posts Button and posts RecyclerView.
Then we add an OnClickListener to the get posts Button to invoke the getPostsUsingVolley() method when the Button is clicked.
Finally in the onCreateView(…) method we initialize the List of Posts to an empty ArrayList which is provided as a parameter to the constructor of the PostsRecyclerViewAdapter. Then we set up the RecyclerView to use a LinearLayoutManager and link the PostsRecyclerViewAdapter to the RecylcerView.
In the getPostsUsingVolley() method we create the URI where we will retrieve the subreddit posts from by joining the base reddit URL for a subreddit with the user entered subreddit name and adding “.json” as the suffix.
Then we use the Volley library to create a JsonObjectRequest object that includes details on the HTTP request type (which in our case is GET), the URI, a listener for handling a successful response and a listener for handling an error response.
In the listener for handling a successful response we will modify the List of Posts to contain an empty ArrayList. Then we will begin parsing the JSON response using the JSONObject and JSONArray classes.
We retrieve all of the Post objects from the JSON response into a JSONArray by accessing the “children” array which exists on the “data” object.
Then we will loop through each JSONObject in the JSONArray of reddit posts and retrieve the post details including the title, number of comments and post score. We pass these details as parameters to the Post constructor and add each Post into the List of Posts.
Once all the Posts are parsed from the JSON response we will notify the RecyclerViewAdapter of the new posts by calling the setPosts(List<Post>) method which will update the RecyclerView with the Posts we have just retrieved.
In the listener for handling an error response we simply show a Toast with the error message.
Finally in the getPostsUsingVolley() method the HTTP request is not made using Volley until we pass the JsonObjectRequest object as a parameter to the addRequestToQueue(…) method defined in the MyRequestQueue class.
Parsing a JSON File from a URL or API Using Retrofit
In this section of the tutorial I will show you how to use the Retrofit library by Square for parsing a JSON file from a URL.
In this section I will reuse the following the components created in the section above for parsing a JSON file from a URL using Volley.
- Post class
- PostRecyclerViewAdapter, PostViewHolder and PostViewHolder layout resource
- SubredditFragment (which we will modify) and SubredditFragment layout resource
First we will add the Gradle dependencies for Retrofit in the app level build.gradle file. Retrofit requires a minimum of Java 8 which also needs to be flagged in the compile options in the build.gradle file.
See the sample build.gradle file containing the Retrofit, RecyclerView and CardView dependencies as well as the Java 8 compile options.
Next we will create a Java interface to be used by Retrofit for creating a HTTP GET request to retrieving a JSON file in the response at a given URI containing posts for a subreddit.
See the code sample for the RedditPostsService interface below.
The GET annotation above the getPosts(…) method declaration lets Retrofit know that we will be using the GET method on the HTTP request when retrieving the subreddit posts.
The curly brackets “{” and “}” around “subreddit” inside the GET annotation indicate that we will be substituting the “subreddit” text with the subreddit String Path parameter defined in getPosts(…). The “.json” will be added as a prefix to the path after the subreddit value is substituted.
Finally the Call<ResponseType> return type for the getPosts(…) method indicates that the HTTP response will create a ResponseType object which comes from the OkHttp3 library which we will use to obtain and parse the JSON response and retrieve the Post records.
Next we will create class for consuming the interface we have just created by building a Retrofit client that will be used to make requests to the retrieve subreddit posts from reddit.com
See the code sample for the MyRetrofitClient class below.
In the MyRetrofitClient we use the Retrofit builder to create a RetroClient for retrieving Posts from Reddit using the interface we previously created. We use the RedditPostsService on the MyRetrofitClient to make a HTTP GET request to reddit.com in the next step in this tutorial.
Now we will make some changes to the existing SubredditFragment class to invoke the method to get the subreddit posts using the RedditPostsService on our instance of the MyRetrofitClient when the user selects the “Get Posts” Button.
See the code sample for the SubredditFragment class below.
In the onCreateView(…) method we have made only one slight change which will invoke the getPostsUsingRetrofit() method when the user selects the “Get Posts” Button.
We have created the new method called getPostsUsingRetrofit() which will be used to parsing a JSON file from a URL or API using Retrofit.
To retrieve the JSON file from reddit we get the instance of the MyRetrofitClient, retrieve the PostsService then invoke the getPosts(String) method passing the subreddit name from the EditText as a parameter.
We then chain the enqueue(…) method to the getPosts(String) method and implement listeners for onResponse(…) and onFailure(…).
In case of a successful response the onResponse(…) method will be invoked. We will first reset the List of Posts to contain an empty ArrayList. Then we will convert the body of the response into a JSON String format by accessing the chain the body() method and the string() method on the ResponseBody parameter.
Once we have the JSON String we will parse it into a JSONObject using the JSONObject constructor with the JSON String as a parameter to the constructor. Now that we have the JSONObject we will follow the same approach documented in the Volley section for retrieving the Post details out of the JSONObject and adding them into the List of Posts.
In case of failure in the response the onFailure(…) will be invoked. We will follow the same pattern we used for Volley and will show a Toast displaying the error message received.
If you would like to learn more about using Retrofit to interact with API or webservices to send and receive JSON data check out the two articles I wrote on this topic below.
Serialization and Deserialization of JSON in Android
In this section of the tutorial I will cover serialization and deserialization of JSON in Android.
Serialization of JSON in Android is the conversion of a Java object into a JSON string. Deserialization of JSON in Android is the conversion of a JSON string into a Java object.
There are multiple libraries that support serialization and deserialization of JSON in Android including libraries such as GSON, Moshi and Jackson. For the purposes of this tutorial we will be using the GSON library published by Google for both serialization and deserialization of JSON.
To use the GSON library you will need to add it as a dependency to your app level build.gradle file. See a sample build.gradle file including the GSON dependency below.
After we have added the GSON library we will then need to update the Post class to add annotations to each of the variables as they appear in the JSON string to allow us to convert between a Java object and a JSON string and vice versa.
To achieve this, we add an annotation SerializedName above each variable and specify the name of the corresponding attribute in the JSON string inside the annotation.
See the code sample for the Post class containing the SerializedName attributes below.
How to Convert a JSON String into a Java Object in Android
In this section of the tutorial I will show you how to convert a JSON string into a Java object in Android using the GSON library. This process is better known as deserialization.
Please see the code sample below containing an updated SubredditFragment class.
In this SubredditFragment class a new method convertJSONToPost(String) has been created. It accepts a JSON String as a parameter and returns a Post object corresponding to the deserialized JSON String.
To convert a JSON String into a Java object using GSON first we create a new GSON object with an empty constructor. After that we will return Post record from calling the fromJson(…) method on the GSON object passing the JSON String and the Post class as parameters.
I have also create a new method called getPostsUsingRetrofitWithGSON() which is almost the same as the getPostsUsingRetrofit() method but on line 82 we use the convertJSONToPost(String) method passing the JSON String of the post in the JSONArray array to convert it into a Post object than add it to the List of Posts.
How to Convert a Java Object into a JSON String in Android
In this section of the tutorial I will show you how to convert a Java object into a JSON string in Android using the GSON library. This process is better known as deserialization.
See the code excerpt below showing the convertPostToJson(Post) method that shows how to convert a Post object to a JSON string using Gson using the toJson(…) method on a new Gson object passing the Post as a parameter.
How to Create a JSON File in Android
In this section of the tutorial I will show you how to create and write a JSON string to a file in internal storage in Android. I will also show you how to read a JSON string from a file in internal storage.
See the code sample below containing two methods. The first for writing a JSON string to a file in internal storage and the second which is for reading a JSON string from a file in internal storage.
In our Android app where we retrieve posts from a subreddit on reddit.com, if we wanted to save these posts in a JSON format in internal storage we would call the writeJSONFile(String, String) method when we retrieve the JSON string from Retrofit or Volley and pass the JSON string along with a file name as parameters.
You may want to call the readJSONFile(String) method passing the same file name inside the onCreateView(…) method when we load the fragment to show a previous set of posts from a subreddit while we wait for the user to input a subreddit and select the “Get Posts” button.
If you would like to learn more about file processing in Android, I recommend you check out the post I wrote linked below.