Change Volley timeout duration
Asked Answered
L

9

205

I use the new Volley framework for Android to do a request to my server. But it timeouts before getting the response, although it does respond.

I tried adding this code:

HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
HttpConnectionParams.setSoTimeout(httpParams, timeoutMs);

in HttpClientStack of the Volley framework to a different integer (50000), but it still times out before 50 seconds.

Is there a way to change the timeout to a long value?

Leaky answered 13/6, 2013 at 18:45 Comment(2)
Possible duplicate: #694497Misology
@AdamStelmaszczyk - this wouldn't be a duplicate as it is about specific details in the Volley framework. The referenced SO question if about the use of the HttpClient class.Urticaria
P
387

See Request.setRetryPolicy() and the constructor for DefaultRetryPolicy, e.g.

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

            @Override
            public void onResponse(JSONObject response) {
                Log.d(TAG, response.toString());
            }
        }, new Response.ErrorListener() {

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

myRequest.setRetryPolicy(new DefaultRetryPolicy(
        MY_SOCKET_TIMEOUT_MS, 
        DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Protractile answered 18/6, 2013 at 21:36 Comment(7)
@Markus override Request.getPriority() to return something besides 'normal'. ImageRequest does this. NOTE: you should be asking this in a separate SO question.Protractile
This is exactly what I was looking for to prevent Volley from discarding my request which takes 15 sec. - Thanx !Ogletree
I just added this for POST requests to disable retry on timeout. It's incredible wrong that Google Developers have decided to set a retry policy on POST requests. Solved my issue. Thanks.Bramwell
@Protractile where should i write DefaultRetryPolicy constructor? Volley.jar is of compiled classes. we cant edit that Request.class right?Suprarenal
@Suprarenal see the sample request constructor that was just added.Protractile
How can I make such a change to be used by all requests. Is there a way to override add method of requestQueue so that all the requests use the same modified retry policy?Shelli
@KumarDeepak You have to subclass *Request class and set the retry policy there. Refer to Androiderson's answerOestrogen
P
243

To handle Android Volley Timeout you need to use RetryPolicy

RetryPolicy

  • Volley provides an easy way to implement your RetryPolicy for your requests.
  • Volley sets default Socket & ConnectionTImeout to 5 secs for all requests.

RetryPolicy is an interface where you need to implement your logic of how you want to retry a particular request when a timeout happens.

It deals with these three parameters

  • Timeout - Specifies Socket Timeout in millis per every retry attempt.
  • Number Of Retries - Number of times retry is attempted.
  • Back Off Multiplier - A multiplier which is used to determine exponential time set to socket for every retry attempt.

For ex. If RetryPolicy is created with these values

Timeout - 3000 ms, Num of Retry Attempts - 2, Back Off Multiplier - 2.0

Retry Attempt 1:

  • time = time + (time * Back Off Multiplier);
  • time = 3000 + 6000 = 9000ms
  • Socket Timeout = time;
  • Request dispatched with Socket Timeout of 9 Secs

Retry Attempt 2:

  • time = time + (time * Back Off Multiplier);
  • time = 9000 + 18000 = 27000ms
  • Socket Timeout = time;
  • Request dispatched with Socket Timeout of 27 Secs

So at the end of Retry Attempt 2 if still Socket Timeout happens Volley would throw a TimeoutError in your UI Error response handler.

//Set a retry policy in case of SocketTimeout & ConnectionTimeout Exceptions. 
//Volley does retry for you if you have specified the policy.
jsonObjRequest.setRetryPolicy(new DefaultRetryPolicy(5000, 
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Panelist answered 4/3, 2014 at 10:47 Comment(4)
Nice answer @Yakiv Mospan.But on your example, the time of the first attempt is 0 + (3000 * 2) instead of 3000 + (3000 * 2). And the second one 6000 + (3000 * 2).Zenia
13KZ, I believe you are still wrong regarding time calculations, see my edit and verify against the volley sourceKemper
Just a reminder for people using this: always use new DefaultRetryPolicy( and make sure to never reuse a RetryPolicy object, as the object is referenced through all the request process, and retry increments are added over the same object timeout value, thus making your future request timeouts grow infinitelyMyopic
how is the connection handshake timeout?Questionless
E
23

Just to contribute with my approach. As already answered, RetryPolicy is the way to go. But if you need a policy different the than default for all your requests, you can set it in a base Request class, so you don't need to set the policy for all the instances of your requests.

Something like this:

public class BaseRequest<T> extends Request<T> {

    public BaseRequest(int method, String url, Response.ErrorListener listener) {
        super(method, url, listener);
        setRetryPolicy(getMyOwnDefaultRetryPolicy());
    }
}

In my case I have a GsonRequest which extends from this BaseRequest, so I don't run the risk of forgetting to set the policy for an specific request and you can still override it if some specific request requires to.

Ecology answered 7/10, 2013 at 21:29 Comment(1)
This should work right? setRetryPolicy(new DefaultRetryPolicy( 1000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));Lucania
G
12
/**
 * @param request
 * @param <T>
 */
public <T> void addToRequestQueue(Request<T> request) {

    request.setRetryPolicy(new DefaultRetryPolicy(
            MY_SOCKET_TIMEOUT_MS,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

    getRequestQueue().add(request);
}
Gamo answered 5/1, 2017 at 9:17 Comment(0)
C
6
req.setRetryPolicy(new DefaultRetryPolicy(
    MY_SOCKET_TIMEOUT_MS, 
    DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

You can set MY_SOCKET_TIMEOUT_MS as 100. Whatever you want to set this to is in milliseconds. DEFAULT_MAX_RETRIES can be 0 default is 1.

Califate answered 7/3, 2018 at 11:1 Comment(0)
R
5
int MY_SOCKET_TIMEOUT_MS=500;

 stringRequest.setRetryPolicy(new DefaultRetryPolicy(
                MY_SOCKET_TIMEOUT_MS,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Redding answered 14/3, 2018 at 9:51 Comment(0)
H
3

Another way of doing it is in custom JsonObjectRequest by:

@Override
public RetryPolicy getRetryPolicy() {
    // here you can write a custom retry policy and return it
    return super.getRetryPolicy();
}

Source: Android Volley Example

Honshu answered 6/2, 2015 at 7:19 Comment(0)
T
2

Alternative solution if all above solutions are not working for you

By default, Volley set timeout equally for both setConnectionTimeout() and setReadTimeout() with the value from RetryPolicy. In my case, Volley throws timeout exception for large data chunk see:

com.android.volley.toolbox.HurlStack.openConnection(). 

My solution is create a class which extends HttpStack with my own setReadTimeout() policy. Then use it when creates RequestQueue as follow:

Volley.newRequestQueue(mContext.getApplicationContext(), new MyHurlStack())
Tarter answered 11/11, 2014 at 5:25 Comment(0)
L
1

I ended up adding a method setCurrentTimeout(int timeout) to the RetryPolicy and it's implementation in DefaultRetryPolicy.

Then I added a setCurrentTimeout(int timeout) in the Request class and called it .

This seems to do the job.

Sorry for my laziness by the way and hooray for open source.

Leaky answered 13/6, 2013 at 19:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.