How to send multiple volley request in a sequence and handle them in a single listener
Asked Answered
P

1

4

In my application I need to send multiple volley request in a sequence. I've create a common listener for dealing with the volley response.

public interface RequestCallBack {
    void onSuccess(JSONObject jsonObject, String tag)
    void OnError(String message);
}

And registered this callback using method:

public void setOnResponseListener (RequestCallBack onResponseListener) {
    this.onResponseListener = onResponseListener;
}

I've created a common method in which volley request is handle.

public void getResponse(String tag, String url) {
    JsonObjectRequest jsonObjectRequest;
    try {

        jsonObjectRequest = new JsonObjectRequest(Request.Method.GET,
                url,null, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {

                try {
                    mStatusCode = response.optInt("status_code");
                    mBody = response.optJSONObject("body");
                    if (mStatusCode != 0 && mStatusCode == 201) {
                        onResponseListener.onSuccess(mBody, (String) jsonObjectRequest.getTag());
                    }

                } catch (JSONException e) {
                    e.printStackTrace();

                }

            }

        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                onResponseListener.OnError(displayVolleyError(error));
            }
        }) {
            @Override
            protected VolleyError parseNetworkError(VolleyError volleyError) {
                if (volleyError.networkResponse != null && volleyError.networkResponse.data != null) {
                    volleyError = new VolleyError(new String(volleyError.networkResponse.data));
                }

                return volleyError;
            }
        };

        jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
                REQUEST_TIMEOUT_MS,
                NO_OF_RETRY_ATTEMPTS,
                BACK_OF_MULTIPLIER));
        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(jsonObjectRequest, tag);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

I've called this method from a class as:

    classObject.getResponse("request1", firstUrl);
    classObject.getResponse("request2", secondUrl);

And I've overrided the RequestCallBack interface methods. But Inside the onSuccess Method each time the tag of 2nd request is returned.

@Override
public void onSuccess(JSONObject jsonObject, String tag) {
    Log.d("Class", "tag: "+tag); // Always returns the "request2"
    // Will check service response according to tag
    // but didn't get the right tag.
}

@Override
public void OnError(String message) {

}

Can anyone suggest me here how to resolve this issue.

Thanks in advance.

Puddle answered 21/9, 2016 at 7:14 Comment(4)
hey I have also created a common approach for using volley and sending requests. If you need i can post my approach with singleton object approachOtherworld
I'm already using the singleton class for creating request queue.Puddle
Are you able to differentiate that the result you are getting is reciving from which service?Otherworld
@PreetikaKaur, Thats the thing which I want. I've used tag for this purpose but it didn't working. Can you help me here ?Puddle
O
4

Application class

import android.app.Application;
import android.text.TextUtils;

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

/**
 * Created by Preetika on 7/4/2016.
 */
public class App extends Application {

    private static App  mInstance;
    public static final String TAG = App.class
            .getSimpleName();
    private RequestQueue mRequestQueue;
    public App() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;


    }
    public static synchronized App getmInstance(){return mInstance;}

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }

        return mRequestQueue;
    }
    public <T> void addToRequestQueue(com.android.volley.Request<T> req, String tag) {
        // set the default tag if tag is empty
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }

}

Create an Enum So that you can set any value whenever you are going to hit any request like below.

public static enum SERVICE_TYPE{
       //set enums here for example you are hitting request for login 
       LOGIN
    }

I have created a common class for sending requests on server.

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import com.acadgild.android.volley.App;
import com.acadgild.android.volley.utils.CommonUtilities;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.StringRequest;

import java.util.Map;

/**
 * Created by Preetika on 6/17/2016.
 */
public class CallAddrVolley extends AsyncTask<Void, Void, Void> {

    private static String TAG= "CallAddr";
    Context context;
    Map<String, String> paramss;
    OnWebServiceResult resultListener;
    CommonUtilities.SERVICE_TYPE Servicetype;
    String url;
    int method;
    private String tag_json_obj = "jobj_req";


    public CallAddrVolley(Context context, Map<String, String> params, int method, String url, CommonUtilities.SERVICE_TYPE Servicetype, OnWebServiceResult resultListener){
        this.context= context;
        this.paramss = params;
        this.url= url;
        this.resultListener= resultListener;
        this.Servicetype= Servicetype;
        this.method= method;
        Log.e("size", "size= "+ paramss.size());
    }


   @Override
    protected Void doInBackground(Void... params) {
     /*  JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
               url, null,
               new Response.Listener<JSONObject>() {

                   @Override
                   public void onResponse(JSONObject response) {
                       Log.d(TAG, response.toString());
                       try {
                           resultListener.getWebResponse(response.toString(), Servicetype);
                       }catch (Exception e){
                           e.printStackTrace();
                       }
                   }
               }, new Response.ErrorListener() {

           @Override
           public void onErrorResponse(VolleyError error) {
               VolleyLog.d(TAG, "Error: " + error.getMessage());
           }
       }) {

           *//**
            * Passing some request headers
            * *//*
           @Override
           public Map<String, String> getHeaders() throws AuthFailureError {
               HashMap<String, String> headers = new HashMap<String, String>();
               headers.put("Content-Type", "application/json");
               return headers;
           }

           @Override
           protected Map<String, String> getParams() {
               Log.e("params", "params= "+ paramss.size());
               Log.e("params", "params= "+ paramss.get(Constants.USER_ID));
               return paramss;
           }

       };*/
       StringRequest myReq = new StringRequest(method,
               url,
               new Response.Listener<String>() {
                   @Override
                   public void onResponse(String response) {
                       Log.e(TAG, response.toString());
                       try {
                           resultListener.getWebResponse(response.toString(), Servicetype);
                       }catch (Exception e){
                           e.printStackTrace();
                       }

                   }
               },
               new Response.ErrorListener() {

                   @Override
                   public void onErrorResponse(VolleyError error) {
                       VolleyLog.d(TAG, "Error: " + error.getMessage());
                   }
               }) {

           protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {

               Log.e("params", "params= "+ paramss.size());
               Log.e(TAG, "Url= "+ url+ paramss.toString());
               return paramss;
           };
       };
       // Adding request to request queue
       App.getmInstance().addToRequestQueue(myReq,
               tag_json_obj);
        return null;
    }

}

Create an interface that you have to include in those classes where you want to hit request so that you can get result and with the help of CommonUtilities.SERVICE_TYPE you will come to know that result is coming from service

 import com.acadgild.android.volley.utils.CommonUtilities;

    /**
     * @author Preetika
     *
     */
    public interface OnWebServiceResult {
        public void getWebResponse(String result, CommonUtilities.SERVICE_TYPE type);
    }

Try it I am using this approach in my projects and it works for me perfectly... If any help is needed let me know....

Otherworld answered 21/9, 2016 at 11:6 Comment(6)
Is it necessary to implement it by using enum, can we achieve it by using a string name ??Puddle
on large scale products enum proves better and easy to implement as you can reuse them whereas if i consider string that will work but not sure how much successful it would be ... instead of enum you can pass string and mae separate class and take strings as constants.. If you want to apply this i can help you in applying this as wellOtherworld
I've implemented it by using integer constant (Benefit of memory consumption). Thank you very much it helps me a lot.Puddle
uh thats great... Kindly accept and upvote the answer if it helps you..:) @PrithnirajNicyoneOtherworld
Yea sure, Will definitely do it :)Puddle
Glad to help you.. :)Otherworld

© 2022 - 2024 — McMap. All rights reserved.