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?

Andrew T.
  • 4,701
  • 8
  • 43
  • 62
Cissmayazz
  • 2,195
  • 3
  • 15
  • 10
  • Possible duplicate: http://stackoverflow.com/questions/693997/how-to-set-httpresponse-timeout-for-android-in-java – Adam Stelmaszczyk Jun 13 '13 at 18:48
  • 24
    @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. – Michael Banzon Jun 13 '13 at 18:51

9 Answers9

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));
Andrew T.
  • 4,701
  • 8
  • 43
  • 62
larham1
  • 11,736
  • 5
  • 35
  • 26
  • 2
    @Markus override Request.getPriority() to return something besides 'normal'. ImageRequest does this. NOTE: you should be asking this in a separate SO question. – larham1 Jun 20 '13 at 00:48
  • 1
    This is exactly what I was looking for to prevent Volley from discarding my request which takes 15 sec. - Thanx ! – slott Nov 02 '13 at 21:56
  • 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. – Juampa Sep 30 '14 at 21:22
  • @larham1 where should i write DefaultRetryPolicy constructor? Volley.jar is of compiled classes. we cant edit that Request.class right? – Roon13 May 15 '15 at 13:56
  • 1
    @Roon13 see the sample request constructor that was just added. – larham1 May 16 '15 at 17:12
  • 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? – Kumar Deepak Mar 08 '16 at 09:40
  • @KumarDeepak You have to subclass `*Request` class and set the retry policy there. Refer to [Androiderson's answer](http://stackoverflow.com/a/19235122/2821954) – Andrew T. Mar 11 '16 at 05:54
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));
I.G. Pascual
  • 5,818
  • 5
  • 42
  • 58
Yakiv Mospan
  • 8,174
  • 3
  • 31
  • 35
  • 5
    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). – 13KZ Jan 01 '15 at 21:45
  • 13KZ, I believe you are still wrong regarding time calculations, see my edit and verify against the volley source – Protongun Jun 29 '16 at 23:20
  • 1
    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 infinitely – I.G. Pascual Nov 28 '16 at 18:39
  • how is the connection handshake timeout? – Sam YC Jan 03 '17 at 09:25
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.

gMale
  • 17,147
  • 17
  • 91
  • 116
Androiderson
  • 16,865
  • 6
  • 62
  • 72
  • 1
    This should work right? setRetryPolicy(new DefaultRetryPolicy( 1000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); – LOG_TAG Feb 05 '15 at 06:38
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);
}
Robert
  • 5,278
  • 43
  • 65
  • 115
chavanNil
  • 161
  • 2
  • 4
5
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.

jps
  • 20,041
  • 15
  • 75
  • 79
Manasvi
  • 450
  • 7
  • 9
5
int MY_SOCKET_TIMEOUT_MS=500;

 stringRequest.setRetryPolicy(new DefaultRetryPolicy(
                MY_SOCKET_TIMEOUT_MS,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Avinash
  • 361
  • 4
  • 16
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

KnowIT
  • 2,392
  • 1
  • 18
  • 16
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())
Uniruddh
  • 4,427
  • 3
  • 52
  • 86
Bao Le
  • 16,643
  • 9
  • 65
  • 68
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.

Uniruddh
  • 4,427
  • 3
  • 52
  • 86
Cissmayazz
  • 2,195
  • 3
  • 15
  • 10