ZOFTINO.COM android and web dev tutorials

Get & Post Data Using HTTP Library Volley in Android

Using any HTTP client, android apps can get data from and post data to server. Using simple http client library in your app requires you to write a lot of code to handle http connections, concurrent requests, threads, pooling, data cache, request prioritization and cancelling requests. Volley is an http framework that offers request scheduling, concurrent request handling, disk and memory based response cache, request prioritization, and request cancellation capabilities out of the box.

You can get and post any type of data using volley framework. Volley offers built-in response handlers to handle string, images and JSON responses. If your app needs to handle other response types than string, image and JSON, you need to write custom request by extending Request class and implementing parseNetworkResponse() and deliverResponse() methods.

Volley is good for transmitting simple application data. If your app features requires large downloads, it is better to use DownloadManager as volley maintains cache for all responses.

You can add volley library to your app project by including dependency in gradle file like "compile 'com.android.volley:volley:1.0.0'".

Since http request and response are transmitted over network, apps using volley needs permission to access internet. You need to request for android.permission.INTERNET permission by adding it to manifest file.

Volley RequestQueue Setup

The main classes you use in volley are Request and RequestQueue. RequestQueue handles threads, cache, response parsing using Request and returning parsed response to main thread. You can create RequestQueue by calling Volley.newRequestQueue method. This method returns RequestQueue with default values for cache and http client.

If want to change default values you can do so by instantiating RequestQueue passing cache object and http client object you want to use to the constructor of RequestQueue and start the instantiated RequestQueue object by calling start() method. Volley offers DiskBasedCache cache and BasicNetwork http-client out of the box.

Since instantiating RequestQueue requires resources, it is a best practice to follow singleton pattern so that only one instance of RequestQueue is created per app and used throughout the app.

Volley RequestQueue Singleton

Singleton pattern is used to make sure only one instance of an object is created in an app. As RequestQueue object shouldn’t be instantiated multiple times, singleton pattern for RequestQueue instantiation is the best choice.

 package com.zoftino.content;

import android.content.Context;

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

public class RequestQueueSingleton {

    private static RequestQueueSingleton requestQueueSingleton;

    private RequestQueue requestQueue;
    private static Context context;

    private RequestQueueSingleton(Context ctx) {
        context = ctx;
        requestQueue = getRequestQueue();
    }
    public static synchronized RequestQueueSingleton getInstance(Context context) {
        if (requestQueueSingleton == null) {
            requestQueueSingleton = new RequestQueueSingleton(context);
        }
        return requestQueueSingleton;
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(context.getApplicationContext());
        }
        return requestQueue;
    }
}
 

Volley Request Flow

Once RequestQueue object is available, you can add requests to it by calling add() method and passing Request object. Volley first checks for response in cache to see if the added request can be severed from the cache. If request can’t be served from cache, it uses network thread and http client to get response from server and saves response in cache before sending parsed response to the main thread.

Cancel Request

Requests added to RequestQueue which are pending can be cancelled by calling cancel() method of Request object. One of the use cases of request cancellation arises when activity needs to stop. In the activity’s onstop callback method, you can call cancel method on request objects to clean up pending requests so that response handlers are not called after activity stops. But you need to hold reference to requests in order to cancel them when the need arises. The best way to cancel group of request is by tagging. Each request in a group is tagged with same identifier before added to request queue. If you want to cancel all requests in the group, you can simply call cancelAll() method on request queue passing tag name as shown in the example.

Volley String Get Request

To get string data, you need to use StringRequest object as shown below. You can add parameters to the url as query string.

String url = getResources().getString(R.string.get_url);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                serverResp.setText("String Response : "+ response);
            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        serverResp.setText("Error getting response");
    }
});
stringRequest.setTag(REQ_TAG);
requestQueue.add(stringRequest);

Volley String Post Request

To perform string data http post using volley, you need to use StringRequest object and pass http method as post to constructor and override getParams() method of Request to add post data as shown below.

final String storeName = "xyz";
final String couponType = "sale";

String url = getResources().getString(R.string.post_url);
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, getPostResponseListener()
                                        , getPostErrorListener()){
    protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
        Map<String, String> params = new HashMap<String, String>();
        params.put("name", storeName);
        params.put("type", couponType);
        return params;
    };
};
stringRequest.setTag(REQ_TAG);
requestQueue.add(stringRequest);

Volley Image Request

To get images, you need to use ImageRequest object as shown below.

String url = getResources().getString(R.string.image_url);
ImageRequest imageRequest = new ImageRequest(url,
        new Response.Listener<Bitmap>() {
            @Override
            public void onResponse(Bitmap response) {
                serverImg.setImageBitmap(response);
            }
        },0, 0,null, null, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        serverResp.setText("Error getting response");
    }
});
imageRequest.setTag(REQ_TAG);
requestQueue.add(imageRequest);

Volley Json Request

To get Json response, you need to use JsonObjectRequest object as shown below.

String url = getResources().getString(R.string.json_get_url);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                serverResp.setText("String Response : "+ response.toString());
            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        serverResp.setText("Error getting response");
    }
});
jsonObjectRequest.setTag(REQ_TAG);
requestQueue.add(jsonObjectRequest);

Volley Json Post Request

To perform Json http post using volley, you need to use JsonObjectRequest object and pass http method as post to constructor and use JsonObject to create post data in json format as shown below.

JSONObject json = new JSONObject();
try {
    json.put("store","amz");
    json.put("category","fashion");
    json.put("type","coupons");
} catch (JSONException e) {
    e.printStackTrace();
}

String url = getResources().getString(R.string.json_get_url);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, json,
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                serverResp.setText("String Response : "+ response.toString());
            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        serverResp.setText("Error getting response");
    }
});
jsonObjectRequest.setTag(REQ_TAG);
requestQueue.add(jsonObjectRequest);

Volley Examples Complete Code

Action

package com.zoftino.content;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.ImageView;
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 com.android.volley.toolbox.ImageRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class VolleyActivity extends AppCompatActivity {

    RequestQueue requestQueue;

    static final int INTERNET_REQ = 23;
    static final String REQ_TAG = "VACTIVITY";
    TextView serverResp;
    ImageView serverImg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_volley);

        serverResp = (TextView)findViewById(R.id.server_resp);
        serverResp.setMovementMethod(new ScrollingMovementMethod());
        serverImg = (ImageView)findViewById(R.id.server_img);

        requestQueue = RequestQueueSingleton.getInstance(this.getApplicationContext())
                .getRequestQueue();
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (requestQueue != null) {
            requestQueue.cancelAll(REQ_TAG);
        }
    }
    public void  getStringResponse(View v){
        String url = getResources().getString(R.string.get_url);
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        serverResp.setText("String Response : "+ response);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                serverResp.setText("Error getting response");
            }
        });
        stringRequest.setTag(REQ_TAG);
        requestQueue.add(stringRequest);
    }
    public void  getStringResponsePost(View v){

        final String storeName = "xyz";
        final String couponType = "sale";

        String url = getResources().getString(R.string.post_url);
        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, getPostResponseListener()
                                                , getPostErrorListener()){
            protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                params.put("name", storeName);
                params.put("type", couponType);
                return params;
            };
        };
        stringRequest.setTag(REQ_TAG);
        requestQueue.add(stringRequest);
    }
    private Response.Listener<String> getPostResponseListener(){
        return new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                serverResp.setText("String Response : "+ response);
            }
        };
    }
    private Response.ErrorListener getPostErrorListener(){
        return new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                serverResp.setText("Error getting response");
            }
        };
    }
    public void  getJsonResponse(View v){

        String url = getResources().getString(R.string.json_get_url);
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        serverResp.setText("String Response : "+ response.toString());
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                serverResp.setText("Error getting response");
            }
        });
        jsonObjectRequest.setTag(REQ_TAG);
        requestQueue.add(jsonObjectRequest);
    }
    public void  getJsonResponsePost(View v){

        JSONObject json = new JSONObject();
        try {
            json.put("store","amz");
            json.put("category","fashion");
            json.put("type","coupons");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        String url = getResources().getString(R.string.json_get_url);
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, json,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        serverResp.setText("String Response : "+ response.toString());
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                serverResp.setText("Error getting response");
            }
        });
        jsonObjectRequest.setTag(REQ_TAG);
        requestQueue.add(jsonObjectRequest);
    }
    public void  getImage(View v){

        String url = getResources().getString(R.string.image_url);
        ImageRequest imageRequest = new ImageRequest(url,
                new Response.Listener<Bitmap>() {
                    @Override
                    public void onResponse(Bitmap response) {
                        serverImg.setImageBitmap(response);
                    }
                },0, 0,null, null, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                serverResp.setText("Error getting response");
            }
        });
        imageRequest.setTag(REQ_TAG);
        requestQueue.add(imageRequest);
    }
}

Action Layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_volley"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.zoftino.content.VolleyActivity">
    <TextView
        android:id="@+id/server_resp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"></TextView>
    <ImageView
        android:id="@+id/server_img"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" ></ImageView>

    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getStringResponse"
        android:text="String Response"></Button>

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getImage"
        android:text="Get Image"></Button>

    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getStringResponsePost"
        android:text="String Post"></Button>

    <Button
        android:id="@+id/button4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getJsonResponse"
        android:text="JSON Response"></Button>

    <Button
        android:id="@+id/button5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getJsonResponsePost"
        android:text="JSON Response Post"></Button>

</LinearLayout>