JSON parsing is a key component in android application development. We can parse JSON data using different third-party libraries like loops, retrofit, and volley. In this tutorial, we will learn how to parse data from url into android using loops. We will develop a complete android JSON parsing example by using a movie JSON file. We will be following the JSON parsing get method and show output data in a custom listview.
Eample JSON data URL
JSON data can be accessed in many ways like storing a json file in raw folder or access from url. In this tutorial we will be following android JSON parsing from URL. We are placing a JSON file named movies.json in our website and access that buy a URL to parse.
we can access JSON data file from this URL: https://tutorialscache.com/movies.json
{
"status":true,
"total_records":10,
"movies": [
{
"id":1,
"name":"Captain America (2011)",
"image":"https://tutorialscache.com/wp-content/uploads/2019/04/captain-america.jpeg",
"ratting":5.0
},
{
"id":2,
"name":"Apocalypto (2006)",
"image":"https://tutorialscache.com/wp-content/uploads/2019/04/apocalypto.png",
"ratting":4.5
},
{
"id":3,
"name":"300 (2006)",
"image":"https://tutorialscache.com/wp-content/uploads/2019/04/300.png",
"ratting":4.5
},{
"id":4,
"name":"Spider Man (2002)",
"image":"https://tutorialscache.com/wp-content/uploads/2019/04/spiderman.jpg",
"ratting":5.0
}
]
}
1. Create new Android Studio Project
Create new android studio project and choose empty activity.



2. strings.xml
We have added few strings to make use in the application.
<resources>
<string name="app_name">Awesome Movies</string>
<string name="network_error">Network not connected</string>
<string name="retry">Retry</string>
<string name="no_status_false">Invalid Response</string>
<string name="no_movies">No Movies Found</string>
</resources>
2.1 colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#d11617</color>
<color name="colorPrimaryDark">#B31718</color>
<color name="colorAccent">#B31718</color>
<color name="white">#FFFFFF</color>
</resources>
3. GlobalClass.java
Create a new class GlobalClass and extend with Application. This class instance will help us to access BASE URL and also gives us application instance. It also has a function named isNetowrk() which will help us to check internet connectivity.
package com.tutorialscache.android_json_parsing;
import android.app.Application;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class GlobalClass extends Application {
public static final String BASE_URL = "http://www.tutorialscache.com/";
private static GlobalClass singleton;
@Override
public void onCreate() {
super.onCreate();
singleton = this;
}
public static GlobalClass getInstance() {
return singleton;
}
public static boolean isNetowrk() {
boolean haveConnectedWifi = false;
boolean haveConnectedMobile = false;
ConnectivityManager cm = (ConnectivityManager)singleton.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
if (ni.isConnected())
haveConnectedWifi = true;
if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
if (ni.isConnected())
haveConnectedMobile = true;
}
return haveConnectedWifi || haveConnectedMobile;
}
}
To launch GlobalClass at start of the application add application name in name attribute in <application> of Android.Manifest.xml
<application
android:name=".GlobalClass"
4. AndroidManifest.xml INTERNET Permissions & NETWORK STATE
We need to add INTERNET & NETWORK STATE Permissions into AndroidManifest.xml file to allow movies.json file from url and to check whether our app is connected with internet or not . These permissions are necessary because we can’t access urls without internet permissions. After adding permissions our AndroidManifest.xml will look like this.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tutorialscache.android_json_parsing">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:name=".GlobalClass"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
5. Third party libraries Loopj & Picasso.
We will use loopj to access data from url and Picasso to load images from url in build.gradle (Module: app)
implementation 'com.loopj.android:android-async-http:1.4.9'
implementation 'com.squareup.picasso:picasso:2.5.2'
build.gradle(Module:app) complete code
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.tutorialscache.android_json_parsing"
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
implementation 'com.loopj.android:android-async-http:1.4.9'
implementation 'com.squareup.picasso:picasso:2.5.2'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
6. WebReq.java
Create a new Application name WebReq and following code. WebReq class used to send request on server. It has GET Method to return JSON data from given url.
package com.tutorialscache.android_json_parsing;
import android.content.Context;
import android.util.Log;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.ResponseHandlerInterface;
public class WebReq {
public static AsyncHttpClient client;
static{
//create object of loopj client
//443 will save you from ssl exception
client = new AsyncHttpClient(true,80,443);
}
// you can create post methods as well similar way
public static void get(Context context, String url, RequestParams params, ResponseHandlerInterface responseHandler) {
client.get(context, getAbsoluteUrl(url), params, responseHandler);
}
//concatenation of base url and file name
private static String getAbsoluteUrl(String relativeUrl) {
Log.d("response URL: ",GlobalClass.getInstance().BASE_URL + relativeUrl+" ");
return GlobalClass.getInstance().BASE_URL + relativeUrl;
}
}
7. activity_main.xml
Add ListView code in activity_main.xml file.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tutorialscache.android_json_parsing.MainActivity">
<ListView
android:id="@+id/listView"
android:scrollbars="none"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
<ProgressBar
android:id="@+id/pBr"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/retryTv"
android:visibility="gone"
android:textColor="@color/colorPrimary"
android:layout_centerHorizontal="true"
android:layout_below="@+id/pBr"
android:text="@string/retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
8. Gradient Image
We need to add a gradient image to make our listview attractive. Download image and place in drawable folder.
9. custom_row.xml
Create a new layout file named custom_row.xml and add following code.
<?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="200dp"
android:padding="0.1dp">
<ImageView
android:id="@+id/movieImg"
android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="200dp" />
<ImageView
android:src="@drawable/gradient"
android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="200dp" />
<TextView
android:id="@+id/movieNameTv"
android:text="300 (2006)"
android:textSize="25dp"
android:textColor="@color/white"
android:layout_alignParentBottom="true"
android:padding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RatingBar
android:id="@+id/movieRating"
style="?android:attr/ratingBarStyleSmall"
android:numStars="5"
android:rating="5"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:paddingBottom="10dp"
android:layout_marginRight="5dp"
android:stepSize="0.1"
android:layout_marginBottom="10dp"
android:isIndicator="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
10. MoviesModel.java
Create a new class named MoviesModel.java and add following code. If you want to learn ho to create model, getters and setters go back to Custom ListView tutorial.
package com.tutorialscache.android_json_parsing;
import android.util.Log;
public class MoviesModel {
//variables
int id;
String name,image;
public double getRatting() {
return ratting;
}
public void setRatting(double ratting) {
this.ratting = ratting;
}
double ratting;
//constructor
public MoviesModel(int id,String name,String image, double ratting){
this.setId(id);
this.setName(name);
this.setImage(image);
this.setRatting(ratting);
}
//getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
@Override
public String toString() {
Log.d("response MODEL: ","ID: "+this.getId()+" Movie Name: "+this.getName()+" Ratting: "+this.getRatting()+" ");
return super.toString();
}
}
11. MoviesJSONAdapter.java
create a new file and name it MoviesJSONAdapter. We will extend this class with BaseAdapter and implement its methods.
package com.tutorialscache.android_json_parsing;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class MoviesJSONAdapter extends BaseAdapter {
MoviesModel moviesModel;
ArrayList<MoviesModel> moviesJsonData;
LayoutInflater layoutInflater;
Context context;
public MoviesJSONAdapter(Context context, ArrayList<MoviesModel> moviesJsonData) {
this.context=context;
this.moviesJsonData=moviesJsonData;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return moviesJsonData.size();
}
@Override
public Object getItem(int position) {
return moviesJsonData.get(position);
}
@Override
public long getItemId(int position) {
return moviesJsonData.get(position).getId();
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
View convertView = view;
if (convertView==null){
convertView = layoutInflater.inflate(R.layout.custom_row,null);
TextView movieNameTv = convertView.findViewById(R.id.movieNameTv);
ImageView movieImg = convertView.findViewById(R.id.movieImg);
RatingBar ratingBar = convertView.findViewById(R.id.movieRating);
moviesModel = moviesJsonData.get(position);
movieNameTv.setText(moviesModel.getName());
//Picasso load image
Picasso.with(context).load(moviesModel.getImage()).into(movieImg);
//set ratting
ratingBar.setRating((float) moviesModel.getRatting());
}
return convertView;
}
}
12. MainActivity.java
package com.tutorialscache.android_json_parsing;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.ResponseHandlerInterface;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import cz.msebera.android.httpclient.Header;
public class MainActivity extends AppCompatActivity {
ListView listView;
TextView retryTv;
MoviesJSONAdapter moviesJSONAdapter;
ArrayList<MoviesModel> moviesJsonData;
ProgressBar progressBar;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context=this;
setContentView(R.layout.activity_main);
initialize();
if (GlobalClass.isNetowrk()){
requestData();
retryTv.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
}else {
Toast.makeText(context,getString(R.string.network_error),Toast.LENGTH_SHORT).show();
retryTv.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.INVISIBLE);
}
}
private void initialize() {
listView = findViewById(R.id.listView);
retryTv = findViewById(R.id.retryTv);
progressBar = findViewById(R.id.pBr);
moviesJsonData=new ArrayList<>();
moviesJSONAdapter = new MoviesJSONAdapter(context,moviesJsonData);
listView.setAdapter(moviesJSONAdapter);
}
private void requestData() {
RequestParams requestParams = new RequestParams();
WebReq.get(context,"movies.json",requestParams,new MainActivity.ResponseHandler());
}
public class ResponseHandler extends JsonHttpResponseHandler {
@Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
// response failure
super.onFailure(statusCode, headers, responseString, throwable);
}
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
//clear all previous data if any
moviesJsonData.clear();
Log.d("response ",response.toString());
//check status of the response
try {
if (response.getBoolean("status")){
// get movies array from response object
JSONArray movies = response.getJSONArray("movies");
//check whether movies array is not empty
if (movies.length()>0){
//loop through movies array and add into moviesJsonData
for (int i = 0; i < movies.length(); i++) {
//get each movie object
JSONObject movie = movies.getJSONObject(i);
//get each movie Object Data
MoviesModel moviesModel = new MoviesModel(movie.getInt("id"),movie.getString("name"),movie.getString("image"),movie.getDouble("ratting"));
moviesModel.toString();
//add object to moviesJsonData array
moviesJsonData.add(moviesModel);
}
//Now notify adapter with new data
moviesJSONAdapter.notifyDataSetChanged();
}else{
Toast.makeText(context,getString(R.string.no_movies),Toast.LENGTH_SHORT).show();
retryTv.setVisibility(View.VISIBLE);
}
}else{
Toast.makeText(context,getString(R.string.no_status_false),Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFinish() {
//hide progress bar
progressBar.setVisibility(View.GONE);
super.onFinish();
}
}
}
