Android volley is sending information twice with image upload
Asked Answered
R

6

9

I am trying to send an image with my post data to my server from android. To accomplish this I base 64 encoded my image to string and sent it using the android volley library. This is causing problems though. For some reason it sometimes sends the post twice, and I cannot figure out why. Below is the function that is called to send the post request. I put a break mark at the String url = "http://domain.com/ajax_ws.php"; and then one at the protected Map<String, String> getParams() { What I found is the String url = ... is only being called once but when it sends two, the protected Map... is called twice. I can't find any documentation on the android volley so I don't know why this is happening. The bitmap is resized so the image string is somewhere between 100k and 200k characters consistently. I thought maybe it was a size issue but my server is receiving the images and decoding them and everything just fine.

 public void Sharing() {

    pd = ProgressDialog.show(getParent(), null, "Please Wait...");
    final String caption = mEtMessage.getText().toString();
    RequestQueue queue = Volley.newRequestQueue(this);
    String url = "http://domain.com/ajax_ws.php";
    StringRequest postRequest = new StringRequest(
            Request.Method.POST,
            url,
            new MyStringListener(),
            new MyErrorListener()
    ) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("token", "secretToken");
            params.put("mode", "createVoucher");
            params.put("user_id", ActivityLogin.id);
            params.put("deal_id", ActivitySharing.id_deal);
            params.put("user_id_company", ActivityRestaurantDetails.res.getId());
            params.put("user_img", pathImage);
            params.put("caption", caption);
            params.put("company_id", ActivityRestaurantDetails.res.getId());
            return params;

        }
    };
    queue.add(postRequest);
}

Any idea why this might be happening?

Reube answered 15/11, 2013 at 21:39 Comment(7)
Just a suggestion: It would be good to extract the anonymous Response.Listener to separate (inner?) class to simplify things and make your code more readable. It's quite cluttered right now and makes half of your screen covered with indents.Dogie
@Secator Thanks, I will do that, this code has been through the wringer, it's all over the place.Reube
I'm facing the exact problem. My further investigation shows that it deals with any slow connection. I tried to debug the Volley library and found a pattern that the double post is caused by the SocketTimeoutException in BasicNetwork class in method "performRequest(Request<?> request)". Everytime the exception is raised, double post happens. Unfortunately I haven't got any solution for this. Let me know your thought. And also, I don't see this related to RetryPolicy. Any number that you put on the RetryPolicy won't affect of fix this.Verner
@user2848783 Did you manage to find a fix for this issue? To stop it posting multiple times?Neisse
@jfry22 I implemented a work around, it's not ideal but works fairly well. I generate a random string on the android that I send with the WS call. Before the function is called on our server, it checks if this random string exists in a log table within the last hour. If it doesn't exist the random string is stored in a table with a time stamp and the function executes. If it does exist, that means the call is a repeat request and it exits. Not the cleanest but it gets the job done.Reube
Thanks for your reply. I've discovered my issue was due to the default retry policy in a volley request. If there is no response after 2.5seconds it retries the request.Neisse
I put the request timeout to 0. Seems it means that there is no timeout. But it solve the multiple request problemVerner
A
4

Volley uses a RetryPolicy for processing requests which by defaults sends the request up to 3 times with an exponential backoff algorithm. Can it be that some request fail and are retried ? Do you get any error/success logs for the first call of the request ?

Ahem answered 15/11, 2013 at 21:44 Comment(2)
You are right. I did some further testing, and it happens with the larger image. This creates another problem though, and that is how to handle this issue. I've got some ideas but lack in experience in this area so I have posted another question here Thank you for your response!Reube
To understand retry policy,please refer this Retry Policy.Retry Policy` contains 3 params RequestTimeOut,Retries,Multiplier.RequestTimeOut is the time where Volley library waits for the Http response. During that time if no response comes, it makes same Http request. The number of retries is made as per Retriesvalue. If Retry Policy =1,and when Request TimeOut is exceeded,it makes the same Http request only once.Driftwood
C
9

I am able to solve this issue by two ways.

First is suggested by Snicolas. Changed the RetryPolicy. Simply set the timeout value to double of the default timeout. Worked fine. You can also try other values.

request.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

Another way is by setting connection.setChunkedStreamingMode(0); in openConnection method HurlStack class.

I am creating my RequestQueue like this requestQueue = Volley.newRequestQueue(context, new HurlStack());

Hope it helps :)

Couplet answered 11/12, 2014 at 11:5 Comment(0)
M
6

Resolution is to edit retry policy which is also explained here: (http://www.techstricks.com/avoid-multiple-requests-when-using-volley/).

However, if overriding does not work for you then, then you may like to revisit your volley caching logic. Because of the soft ttl in volley caching the result gets delivered from the cache and at the same time it queues another network request which also will return a result. And therefore, single request but two different results.

Multivalent answered 4/12, 2015 at 13:32 Comment(0)
A
4

Volley uses a RetryPolicy for processing requests which by defaults sends the request up to 3 times with an exponential backoff algorithm. Can it be that some request fail and are retried ? Do you get any error/success logs for the first call of the request ?

Ahem answered 15/11, 2013 at 21:44 Comment(2)
You are right. I did some further testing, and it happens with the larger image. This creates another problem though, and that is how to handle this issue. I've got some ideas but lack in experience in this area so I have posted another question here Thank you for your response!Reube
To understand retry policy,please refer this Retry Policy.Retry Policy` contains 3 params RequestTimeOut,Retries,Multiplier.RequestTimeOut is the time where Volley library waits for the Http response. During that time if no response comes, it makes same Http request. The number of retries is made as per Retriesvalue. If Retry Policy =1,and when Request TimeOut is exceeded,it makes the same Http request only once.Driftwood
C
4

The below fix worked for me. Those who work with HTTPS and volley should try this.

DefaultRetryPolicy  retryPolicy = new DefaultRetryPolicy(0, -1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        jsr.setRetryPolicy(retryPolicy);

Hope this will help you to resolve the issue.

Colotomy answered 29/7, 2015 at 14:55 Comment(1)
Thanks. Yours helps alot. DefaultRetryPolicy retryPolicy = new DefaultRetryPolicy(0, -1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); final RequestQueue requestQueuetnn = Volley.newRequestQueue(Activity.this,hurlStacktnn); requestQueuetnn.add(stringRequesttnn); stringRequesttnn.setRetryPolicy(retryPolicy);Holism
C
1

Try this one.

JsonObjectRequest jsonObjRequest = new JsonObjectRequest(...);
jsonObjRequest.setRetryPolicy(new DefaultRetryPolicy(0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Checker answered 7/11, 2016 at 3:27 Comment(0)
W
1

edit the retry number to 1. it worked for me.

stringRequest.setRetryPolicy(new
          DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, 1, 
                           DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)
                );
Westonwestover answered 9/11, 2017 at 13:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.