Mobile
Article

Volley, a Networking Library for Android

By Valdio Veliu

Using Android Studio? Download our Handy Cheat Sheet of Keyboard Shortcuts!

This article was updated on 21st December, 2016. Specifically: new entry, updated deprecated code and added a new section for image loading.

Networking with Volley in Android

Networking has been around since day zero of mobile technologies and Android is not different. What has changed is the way network operations are handled. The focus of networking libraries such as Volley has been the automation of the network operations.

Until HoneyComb, network calls ran from the main thread and in subsequent Android versions, network requests executed asynchronously from the main thread. To make a network call, a developer needs to implement an Asynctask in a different thread from the main application thread or a NetworkOnMainThreadException will be thrown.

A short overview of Volley

Volley is a networking library for Android that manages network requests. It bundles the most important features you’ll need, such as accessing JSON APIs, loading images and String requests in an easier-to-use package.

By using Volley for network operations you avoid the standard way to handle networking, HttpURLConnection. Another reason is asynchronicity. Volley handles asynchronicity by itself, there is no need to create Asynctask manually.

Based on the documentation, the core of every network operation performed by Volley is the RequestQueue. Working with Volley is handled by creating a RequestQueue and passing it Request objects. The RequestQueue manages worker threads for running the network operations, reading from and writing to the cache, and parsing responses.

Volley offers a variety of features, as mentioned in its documentation:

  1. Automatic scheduling of network requests.
  2. Multiple concurrent network connections.
  3. Caching.
  4. Request prioritization.
  5. Cancellation of ongoing API requests.

These are the core benefits that this library provides and the main focus of this article.

Import Volley, add Permissions

Before getting started with Volley, you need to configure your Android project.
Create a new Android project. Open build.gradle(Module: app) and add the following dependency.

dependencies {
    //...

    compile 'com.android.volley:volley:1.0.0'
}

In AndroidManifest.xml add the internet permission.

<uses-permission android:name="android.permission.INTERNET" />

Standard Network Requests

As I previously mentioned, the core of every network operation performed by Volley is the RequestQueue. Every request made to the network is passed to the RequestQueue trough Request objects.
There are three types of requests, JSON requests, Image requests and String requests. I will go through each of these types with explanations and code examples.

For now, in MainActivity’s onCreate() method, initiate the RequestQueue.

    RequestQueue requestQueue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //...
        requestQueue = Volley.newRequestQueue(this); // 'this' is the Context

    }

JSON Requests

Volley has Requests for JSONObject and JSONArray. The structure of JSONRequest and most of the request classes included in Volley uses constructors like the following.

JsonObjectRequest request JsonObjectRequest(RequestMethod, URL, null,  new ResponseListener(), new ErrorListener());

Parameters passed into the constructor:

  • RequestMethod (GET, POST, PUT, DELETE, etc.)
  • URL: String of the URL of the required object
  • JSONObject: An optional object posted with the request, null if there is no object posted
  • ResponseListener: Response Listener, whose callback method will contain the response
  • ErrorListener: A Response.ErrorListener whose callback method will contain any problem with the request.

The following code snippets are the complete implementation of both JsonObjectRequest and JsonArrayRequest respectively.

        /*Json Request*/
   String url = "https://json_url/";
   JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
           new Response.Listener<JSONObject>() {
               @Override
               public void onResponse(JSONObject response) {

               }
           },
           new Response.ErrorListener() {
               @Override
               public void onErrorResponse(VolleyError error) {

               }
           });
   //add request to queue
   requestQueue.add(jsonObjectRequest);

   JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null,
           new Response.Listener<JSONArray>() {
               @Override
               public void onResponse(JSONArray response) {

               }
           },
           new Response.ErrorListener() {
               @Override
               public void onErrorResponse(VolleyError error) {

               }
           });
   //add request to queue
   requestQueue.add(jsonArrayRequest);

Now that I’ve shown how to receive JSON data in Android, let’s see how to post data with Volley.

The request is the same format as receiving JSON data with the exception that you must specify a JSONObject posted with the request and request headers for sending data from the client to server side.

    /*Post data*/
    Map<String, String> jsonParams = new HashMap<String, String>();

jsonParams.put("email", "user@gmail.com");
jsonParams.put("username", "user");
jsonParams.put("password", "pass");

    JsonObjectRequest postRequest = new JsonObjectRequest( Request.Method.POST, URL,

          new JSONObject(jsonParams),
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                  //   Handle Error
                }
            }) {
        @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");
            headers.put("User-agent", System.getProperty("http.agent"));
            return headers;
        }
    };
requestQueue.add(postRequest);

Note that the request headers might have to change depending on the development use case.

String Request

This type of request is used to retrieve data from a server as a String.

   /*String Request*/
   String url = "https://string_url/";
   StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
           new Response.Listener<String>() {
               @Override
               public void onResponse(String response) {

               }
           },
           new Response.ErrorListener() {
               @Override
               public void onErrorResponse(VolleyError error) {

               }
           });
   //add request to queue
   requestQueue.add(stringRequest);

The structure of the StringRequest contains a request method (POST or GET), a URL to the String source, a Response.Listener and a Response.ErrorListener. Pretty much the same as the JsonRequest.

Image Request

Volley offers a few ways to load images in Android. I will go through all of them to explain their differences and provide some code samples.

ImageRequest

ImageRequest is a way to load images for getting an image at a given URL. The structure of this network call is similar to the other requests previously presented.
The following code is an example of an ImageRequest to load an image into an ImageView.

   int maxWidth = ...;
   int maxHeight = ...;
   String URL = "http://image_url.png";
   ImageRequest imageRequest = new ImageRequest(URL, new Response.Listener<Bitmap>() {
       @Override
       public void onResponse(Bitmap response) {
           // Assign the response to an ImageView
           ImageView imageView = (ImageView) findViewById(R.id.imageView);
           imageView.setImageBitmap(response);
       }
   }, maxWidth, maxHeight, null);
   //add request to queue
   requestQueue.add(imageRequest);

The structure of the ImageRequest is straightforward. It needs the image’s URL, a Response Listener, whose callback method will contain the image Bitmap as a response, a maxWidth and maxHeight, a Config format to decode the bitmap to, and a Response.ErrorListener for any response errors. Add the request to the RequestQueue and the Android runtime will handle the rest.

ImageLoader

ImageLoader is a helper class to handle loading and caching images from remote URLs. This request is useful for a large number of ImageRequest. According to the documentation ImageLoader provides an in-memory cache to sit in front of the normal Volley cache, which is important to prevent flickering.

NetworkImageView

NetworkImageView is an efficient way to replace ImageView when images are being loaded from the network.

The following code snippets provide an implementation of both the two last sections of image loading with Volley. The following VolleySingleton class is an implementation of a RequestQueue. This singleton class has caching capabilities with in-memory LRU cache. The LruCache is set up to store up to 30 elements.

import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.util.Log;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

public class VolleySingleton {
    private static VolleySingleton singletonInstance = null;
    private RequestQueue requestQueue;
    private ImageLoader imageLoader;

    private VolleySingleton(Context context) {
        requestQueue = Volley.newRequestQueue(context);
        imageLoader = new ImageLoader(this.requestQueue, new ImageLoader.ImageCache() {
            private final LruCache<String, Bitmap> lruCache = new LruCache<String, Bitmap>(30);
            //30 -> the maximum number of entries in the cache.

            public void putBitmap(String url, Bitmap bitmap) {
                lruCache.put(url, bitmap);
                Log.d("CachedItems", String.valueOf(lruCache.size()));
            }

            public Bitmap getBitmap(String url) {
                return lruCache.get(url);
            }
        });
    }

    public static VolleySingleton getInstance(Context context) {
        if (singletonInstance == null) {
            singletonInstance = new VolleySingleton(context);
        }
        return singletonInstance;
    }

    public RequestQueue getRequestQueue() {
        return this.requestQueue;
    }

    public ImageLoader getImageLoader() {
        return this.imageLoader;
    }
}

Now that the VolleySingleton class is setup, lets load an image into a NetworkImageView. But first, add an instance int the Activity’s layout file. Here is an example:

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/networkImageView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

Finally, load an image into the NetworkImageView. In the in MainActivity’s onCreate() method add this code.

    private ImageLoader imageLoader;
    private NetworkImageView imageView;
    private static final String IMAGE_URL = "https://the_images_url.jpg";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //...

        imageLoader = VolleySingleton.getInstance(getApplicationContext()).getImageLoader();
        imageView = (NetworkImageView) findViewById(R.id.networkImageView);
        imageView.setImageUrl(IMAGE_URL, imageLoader);

    }

To make sure the cache works properly, I added a Log statement in the VolleySingleton class. Run the project and check the Log in Android Studio. Each time a new image is cached the device prints out a number of cached items.

Request Prioritization

Handling network requests means prioritizing what’s needed and how fast the response is needed since networking is a real time operation.

Volley processes the requests from higher priorities to lower priorities, in first-in-first-out order. There is no setPriority() method, so to prioritize a request, some work is needed.

Here is an example of a custom JsonObjectRequest class that can make priority requests. The focus of this class is on the overridden getPriority() method. When the request is added to the queue this method will return the priority assigned to it by setPriority(), or will return Priority.HIGH assigned inside the class, but it won’t search for a priority outside this class.

The same structure applies to all the other request types.

public class CustomPriorityRequest extends JsonObjectRequest {

    Priority priority = Priority.HIGH;

    public CustomPriorityRequest(int method, String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
        super(method, url, jsonRequest, listener, errorListener);
    }

    public CustomPriorityRequest(String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
        super(url, jsonRequest, listener, errorListener);
    }

    @Override
    public Priority getPriority() {
        return priority;
    }

    public void setPriority(Priority p){
        priority = p;
    }
}

Making a request with this new class is the same as the standard requests. You have the ability to set a request priority before adding it to the queue.

   CustomPriorityRequest customPriorityRequest = new CustomPriorityRequest(
           Request.Method.GET, URL, null,
           new Response.Listener<JSONObject>(),
           new Response.ErrorListener());

   customPriorityRequest.setPriority(Request.Priority.IMMEDIATE);
   requestQueue.add(customPriorityRequest);

Some available priorities are: Priority.LOW, Priority.NORMAL, Priority.HIGH and Priority.IMMEDIATE.

Cancel Requests

Another useful tool in Volley is the ability to cancel the requests. Canceling requests is useful when the user closes the app or performs an action that results in not using the responses of the Volley requests. There is no sense executing the remaining requests in the queue, so we cancel them in the onStop() method.

The easiest way to cancel requests in Volley is to add a tag to the request and when the queued requests need to be canceled, call the cancelAll() method. This will cancel all the requests specified with that specific tag.

request.setTag("TAG");

requestQueue.cancelAll("TAG");

Once cancelAll() executes from the main thread, the remaining responses will not be delivered.

  • Aleksander Koko

    If you add Otto (event bus) on the list than it can be even cooler :)

    • http://aziflaj.github.io/ Aldo Ziflaj

      Try RxAndroid with that and see which one is cooler :D

      • Aleksander Koko

        Had just a quick look on it, but Otto is simpler I think. Just a Singleton and ready to go.

      • Aleksander Koko

        Had just a quick look on it, but Otto is simpler I think. Just a Singleton and ready to go.

  • Valdio Veliu

    Thank you for your opinion .

    I thinks it is a matter of preference which of this
    networking libraries you use. They all are great, I’ve tried them.

    Sure Picasso is great and I have to say it’s better than
    Volley in the handling images, after all Picasso is totally focused on image
    loading.

    In my opinion the advantage of Volley is that Volley tries
    to solve a more general problem. Sure it’s more complex to use than the others
    but it is a very powerful tool.

  • http://www.mobileapptelligence.com/ kailash mobileapptelligence

    Top apps can’t be developed newcomers. They may code it but can’t build enterprise ready app. You must find a company with more than 5 years of experience in developing the business apps. In India, top android app development companies are delivering next in class apps to global clients. Mobileapptelligence [dot] com, an award winning Android app development company, is delivering best in class Android apps to global clients.

  • Ashish Singh

    Can you share some ideas, How to send the image on server using volley ?

  • Frank Arkhurst Odoom

    how do u check network response and open another intent i always get cannot convert string to jsonObject error

    • Valdio Veliu

      Probably the response you receive is not in JSON format … Check if the API you make the call to returns JSON.

  • amir mohsenian

    Hi , i can’t download String with 2G or 3G internet in volley . please help me

  • TARUN UMATH

    Thanks for Json Post Code
    It work for me

Recommended
Sponsors
Get the latest in Mobile, once a week, for free.