Most of the android apps are a subset of their web apps. Other type of android applications are those which use network to store some data online like most of the games. Therefore majority of the android applications perform network interactions. Like consuming web services, uploading data etc. Being an android developer you must know that you cant perform network interactions on main thread. As it throws an android.os.NetworkOnMainThreadException. To ease the development, a new framework was introduced recently, called Android Volley Framework. This framework is available through the open AOSP repository. In this tutorial we will make a working Android Volley Example.
This Framework was designed keeping in mind that in Android network requests are not performed on main thread. Hence Android Volley performs all the network operations in worker threads, still it makes the process of making an API call to the network very easy. In this tutorial I would show a simple Android Volley Example. Until now no such framework was available in Android through which one can perform network requests with such minimal coding.
Android Studio: Adding a library to your project
Android Volley framework is distributed in form of a library project which is available at the open AOSP repository. As of now there are two ways to include and use Volley in your project. You can use either one of them. But as expected, the Library project would always have the latest code, and on the contrary side gradle dependency way would by very easy to use:
Gradle Dependency
Include a gradle dependency in your project’s build.gradle (app) file:
compile 'com.android.volley:volley:1.0.0'
Include project like a library
Steps for downloading it and adding it to your project in Android Studio are:
- Clone the repo from this url:
git clone https://android.googlesource.com/platform/frameworks/volley
It can be done through any of the leading tools like Atlassian SourceTree, TortoiseGIT or through the GIT command line.
- In Android Studio go to File-> New-> Import Module -> Specify the directory
- Enter the module name- “:Volley” (for internal project reference), hit finish.
- By now the gradle would start building the project. Let it complete.
- Open build.gradle file for your app module
- In dependencies block add a line
compile project(':Volley')
- Go to Build menu -> Rebuild Project
- You are done importing Android Volley to you project.
Making an Android Volley Example
Earlier in Android to make a webservice or an API call we were supposed to use DefaultHttpClient
class. Through which an HTTP request was executed. But now through this Android Volley example we would learn a way through which asynchronous HTTP REST API calls can be made. Volley library makes it very easy for developers to customize and prioritize requests. It also provides a method through which, one can cancel a single or multiple requests that are in request queue.
The interesting part of volley framework is that, it is pre configured to support multiple types of requests like:
- JSON Object Request – Through class
JsonObjectRequest
. - JSON Array Request – Through class
JsonArrayRequest
. - String Request – Through class
StringRequest
. - Image Transfer Request – Through class
ImageRequest
.
Most commonly used data type for an API call nowadays is a JSON object. Therefore in this Android Volley Example I would show how to send a JSON object request. To do so we will create a custom volley request queue in a singleton pattern.
Android Volley Request Queue
In volley framework one of the most important classes is the RequestQueue
class. This class works in a FIFO (First In First Out) manner. That is when a request in added in the queue, it is inserted at the tail, and at time of execution, request is pulled out from the front.
Android Volley Multiple Requests : How Many Requests?
A question that would come in every developers mind is that, at a time how many requests can android volley make? The ans is, at a time volley can execute 4 requests simultaneously. In default implementation of volley network thread pool size is 4:
DEFAULT_NETWORK_THREAD_POOL_SIZE = 4
Android Volley Caching of Requests
Another interesting feature of volley is that when a request queue is created, and a request is added in it. It is not like that this request would be sent to a worker thread immediately for execution. First it is checked in the Android Volley cache of requests. Is this request is in the waiting request queue at the moment or not? This check is made through the URL of this request. If they match this new request is not executed and old request is replaced with new request object.
Further lets have a look at our custom volley request queue class:
package com.truiton.volleyexample; import android.content.Context; import com.android.volley.Cache; import com.android.volley.Network; import com.android.volley.RequestQueue; import com.android.volley.toolbox.BasicNetwork; import com.android.volley.toolbox.DiskBasedCache; import com.android.volley.toolbox.HurlStack; /** * Custom implementation of Volley Request Queue */ public class CustomVolleyRequestQueue { private static CustomVolleyRequestQueue mInstance; private static Context mCtx; private RequestQueue mRequestQueue; private CustomVolleyRequestQueue(Context context) { mCtx = context; mRequestQueue = getRequestQueue(); } public static synchronized CustomVolleyRequestQueue getInstance(Context context) { if (mInstance == null) { mInstance = new CustomVolleyRequestQueue(context); } return mInstance; } public RequestQueue getRequestQueue() { if (mRequestQueue == null) { Cache cache = new DiskBasedCache(mCtx.getCacheDir(), 10 * 1024 * 1024); Network network = new BasicNetwork(new HurlStack()); mRequestQueue = new RequestQueue(cache, network); // Don't forget to start the volley request queue mRequestQueue.start(); } return mRequestQueue; } }
Here in the class above we have used a singleton pattern for RequestQueue implementation. So that at a time only one request queue can exist in the application. This class is should be initialized with the application context, by doing this we would make this queue last till the app lasts. An important thing to note here is that we are making a custom cache in this Android Volley Example of 10 MB. The default implementation only allows for 5 MB of cache.
Before making a request queue we may need to do some basic things to make this Android Volley Example to work.
Add this in manifest:
<uses-permission android:name="android.permission.INTERNET"/>
Next we would be making a custom JSON object request:
package com.truiton.volleyexample; import com.android.volley.AuthFailureError; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.RetryPolicy; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.StringRequest; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; public class CustomJSONObjectRequest extends JsonObjectRequest { public CustomJSONObjectRequest(int method, String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) { super(method, url, jsonRequest, listener, errorListener); } @Override public Map<String, String> getHeaders() throws AuthFailureError { HashMap<String, String> headers = new HashMap<String, String>(); headers.put("Content-Type", "application/json; charset=utf-8"); return headers; } @Override public RetryPolicy getRetryPolicy() { // here you can write a custom retry policy return super.getRetryPolicy(); } }
The above class is a custom JsonObjectRequest for volley example. Mostly when working for enterprise applications we need to specify some default parameters, like Accept
, and various other authentication headers. Therefore instead of adding headers in every request one can use the getHeaders()
method to specify the default headers which are required to be sent in every request. In this class you can also write a custom retry policy for your request by using the method getRetryPolicy()
. Also this will be applicable on all the requests.
Next lets define the main activity class where all the above classes would come into action.
package com.truiton.volleyexample; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import org.json.JSONException; import org.json.JSONObject; public class MainVolleyActivity extends AppCompatActivity implements Response.Listener, Response.ErrorListener { public static final String REQUEST_TAG = "MainVolleyActivity"; private TextView mTextView; private Button mButton; private RequestQueue mQueue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_volley); mTextView = (TextView) findViewById(R.id.textView); mButton = (Button) findViewById(R.id.button); } @Override protected void onStart() { super.onStart(); // Instantiate the RequestQueue. mQueue = CustomVolleyRequestQueue.getInstance(this.getApplicationContext()) .getRequestQueue(); String url = "http://api.openweathermap.org/data/2.5/weather?q=London,uk"; final CustomJSONObjectRequest jsonRequest = new CustomJSONObjectRequest(Request.Method .GET, url, new JSONObject(), this, this); jsonRequest.setTag(REQUEST_TAG); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mQueue.add(jsonRequest); } }); } @Override protected void onStop() { super.onStop(); if (mQueue != null) { mQueue.cancelAll(REQUEST_TAG); } } @Override public void onErrorResponse(VolleyError error) { mTextView.setText(error.getMessage()); } @Override public void onResponse(Object response) { mTextView.setText("Response is: " + response); try { mTextView.setText(mTextView.getText() + "\n\n" + ((JSONObject) response).getString ("name")); } catch (JSONException e) { e.printStackTrace(); } } }
In the above activity class we are simply creating a custom volley RequestQueue and a custom JsonObjectRequest, with a tag. After the request is created, on click of a button it is added into the custom RequestQueue through the method .add()
. Once the add method is called the request is queued for execution.
Another feature of volley is that, a request can be cancelled at anytime by calling a method cancel()
on the CustomJSONObjectRequest
. Or if you have specified a tag for a request, like in the class above, you can cancel all the requests for that tag with a single method call cancelAll()
. This method can be called from the RequestQueue
.
We have a simple layout for the above activity:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainVolleyActivity" android:background="#FFFFFF"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView" android:src="@drawable/truiton_short" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send Request" android:id="@+id/button" android:layout_below="@+id/imageView" android:layout_alignLeft="@+id/imageView" android:layout_alignStart="@+id/imageView" android:layout_alignRight="@+id/imageView" android:layout_alignEnd="@+id/imageView" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textView" android:layout_below="@+id/button" android:layout_marginTop="26dp" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" /> </RelativeLayout>
This would look something like this :
To have a better understanding, please have a look at the full source code for this example:
With this we would like to conclude this Android Volley Example. If it helped you please share it with your friends and like our Facebook, Google+ page.
Born in New Delhi, India. A software engineer by profession, an android enthusiast and an evangelist. My motive here is to create a group of skilled developers, who can develop something new and good. Reason being programming is my passion, and also it feels good to make a device do something you want. In a very short span of time professionally I have worked with many tech firms. As of now too, I am employed as a senior engineer in a leading tech company. In total I may have worked on more than 20 projects professionally, and whenever I get spare time I share my thoughts here at Truiton.
Thank you! Very Nice!
Thanks for the awesome post
Thats a clear and well done explanation!! thanks
hello bro,
can you explain how to send 5 image with one request using volley library.
Thank you for this example !!
Nice explanation mohit keep it up…
Android Studio: Adding a library to your project
You may like to place the second step as File-> New-> Import Module -> Specify the directory
Thanks.. updated the post.
You are awesome!!!! Iam a beginner and it was very easy to run!!!! And it wirks really!!!
Thank you! Great tutorial.
any examples of using getHeaders() would also be appreciated.
Thank You Good explanation..
Can you please add how to do two or more network requests..??
As to how to handle responses from two or more network requests..
Thanks in Advance
hi Bro,
if we add multiple request (Different response/Api) in mQueue, then how we will identify the response, is belong to which API/Response