Cambiar la duración del tiempo de espera de Volley

191

Uso el nuevo marco Volley para Android para hacer una solicitud a mi servidor. Pero se agota el tiempo de espera antes de obtener la respuesta, aunque sí responde.

Intenté agregar este código:

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

en HttpClientStackel marco de Volley a un número entero diferente (50000), pero aún así agota el tiempo de espera antes de 50 segundos.

¿Hay alguna manera de cambiar el tiempo de espera a un valor largo?

Cissmayazz
fuente
Posible duplicado: stackoverflow.com/questions/693997/…
Adam Stelmaszczyk
21
@AdamStelmaszczyk: esto no sería un duplicado, ya que se trata de detalles específicos en el marco de Volley. La pregunta SO referenciada se refiere al uso de la HttpClientclase.
Michael Banzon

Respuestas:

359

Ver Request.setRetryPolicy()y el constructor de DefaultRetryPolicy, por ejemplo

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));
larham1
fuente
¿También sabe cómo establecer la prioridad de una solicitud?
Markus
2
@ Markus anula Request.getPriority () para devolver algo además de 'normal'. ImageRequest hace esto. NOTA: debe hacer esto en una pregunta SO separada.
larham1
1
Esto es exactamente lo que estaba buscando para evitar que Volley descarte mi solicitud, que demora 15 segundos. - Gracias!
slott
Acabo de agregar esto para las solicitudes POST para deshabilitar el reintento en el tiempo de espera. Es increíblemente malo que los desarrolladores de Google hayan decidido establecer una política de reintento en las solicitudes POST. Resuelto mi problema Gracias.
Proverbio
1
@ Roon13 vea el constructor de solicitud de muestra que se acaba de agregar.
larham1
226

Para manejar Android Volley Timeout necesita usar RetryPolicy

RetryPolicy

  • Volley proporciona una manera fácil de implementar su RetryPolicy para sus solicitudes.
  • Volley establece el valor predeterminado de Socket & ConnectionTImeout en 5 segundos para todas las solicitudes.

RetryPolicy es una interfaz en la que necesita implementar su lógica de cómo desea volver a intentar una solicitud en particular cuando ocurre un tiempo de espera.

Se ocupa de estos tres parámetros.

  • Tiempo de espera: especifica el tiempo de espera de socket en milis por cada intento de reintento.
  • Número de reintentos: número de veces que se intenta reintentar.
  • Multiplicador de retroceso: un multiplicador que se utiliza para determinar el tiempo exponencial establecido en socket para cada intento de reintento.

Por ej. Si RetryPolicy se crea con estos valores

Tiempo de espera: 3000 ms, número de intentos de reintento - 2, multiplicador de retroceso - 2.0

Intento de reintento 1:

  • tiempo = tiempo + (tiempo * Multiplicador de retroceso);
  • tiempo = 3000 + 6000 = 9000ms
  • Socket Timeout = tiempo;
  • Solicitud enviada con tiempo de espera de 9 segundos

Intento de reintento 2:

  • tiempo = tiempo + (tiempo * Multiplicador de retroceso);
  • tiempo = 9000 + 18000 = 27000ms
  • Socket Timeout = tiempo;
  • Solicitud enviada con un tiempo de espera de 27 segundos

Por lo tanto, al final del Reintento Intento 2 si todavía se agota el tiempo de espera de Socket, Volley arrojaría un TimeoutErrorcontrolador de respuesta de error de UI.

//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));
Yakiv Mospan
fuente
Gracias por una respuesta detallada sobre lo que RetryPolicyrealmente hace la implementación.
dbm
55
Buena respuesta @Yakiv Mospan. Pero en su ejemplo, el momento del primer intento es 0 + (3000 * 2) en lugar de 3000 + (3000 * 2). Y el segundo 6000 + (3000 * 2).
13KZ
13KZ, creo que todavía estás equivocado con respecto a los cálculos de tiempo, mira mi edición y
verifícalo
1
Solo un recordatorio para las personas que usan esto: siempre use new DefaultRetryPolicy(y asegúrese de nunca reutilizar un RetryPolicyobjeto, ya que se hace referencia al objeto a través de todo el proceso de solicitud, y se agregan incrementos de reintento sobre el mismo valor de tiempo de espera del objeto, lo que hace que sus futuros tiempos de espera de solicitud crezcan infinitamente
IG Pascual
¿Cómo es el tiempo de espera de conexión?
GMsoF
23

Solo para contribuir con mi enfoque. Como ya respondí, RetryPolicyes el camino a seguir. Pero si necesita una política diferente a la predeterminada para todas sus solicitudes, puede establecerla en una clase de Solicitud base, por lo que no necesita establecer la política para todas las instancias de sus solicitudes.

Algo como esto:

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

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

En mi caso, tengo una GsonRequest que se extiende desde esta BaseRequest, por lo que no corro el riesgo de olvidar establecer la política para una solicitud específica y aún puede anularla si alguna solicitud específica lo requiere.

Androiderson
fuente
1
Esto debería funcionar bien? setRetryPolicy (nuevo DefaultRetryPolicy (1000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
LOG_TAG
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);
}
chavanNil
fuente
7
req.setRetryPolicy(new DefaultRetryPolicy(
    MY_SOCKET_TIMEOUT_MS, 
    DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

Puede establecer MY_SOCKET_TIMEOUT_MScomo 100. Lo que quiera establecer es en milisegundos. DEFAULT_MAX_RETRIESpuede ser 0 por defecto es 1.

Manasvi
fuente
4
int MY_SOCKET_TIMEOUT_MS=500;

 stringRequest.setRetryPolicy(new DefaultRetryPolicy(
                MY_SOCKET_TIMEOUT_MS,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Avinash
fuente
3

Otra forma de hacerlo es en JsonObjectRequest personalizado por:

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

Fuente: Ejemplo de Android Volley

Lo sé
fuente
2

Solución alternativa si todas las soluciones anteriores no funcionan para usted

Por defecto, Volley establece un tiempo de espera igual para ambos setConnectionTimeout()y setReadTimeout()con el valor de RetryPolicy. En mi caso, Volleylanza una excepción de tiempo de espera para un gran fragmento de datos, consulte:

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

Mi solución es crear una clase que se extienda HttpStackcon mi propia setReadTimeout()política. Luego úselo cuando cree de la RequestQueuesiguiente manera:

Volley.newRequestQueue(mContext.getApplicationContext(), new MyHurlStack())
Bao Le
fuente
1

Terminé agregando un método setCurrentTimeout(int timeout)al RetryPolicyy su implementación en DefaultRetryPolicy.

Luego agregué un setCurrentTimeout(int timeout)en la clase Solicitud y lo llamé.

Esto parece hacer el trabajo.

Perdón por mi pereza por cierto y hurra por el código abierto.

Cissmayazz
fuente