Modifica la durata del timeout di Volley


191

Uso il nuovo framework Volley per Android per fare una richiesta al mio server. Ma scade prima di ottenere la risposta, anche se risponde.

Ho provato ad aggiungere questo codice:

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

nel HttpClientStackframework Volley con un numero intero diverso (50000), ma scade ancora prima di 50 secondi.

C'è un modo per cambiare il timeout su un valore lungo?



21
@AdamStelmaszczyk - questo non sarebbe un duplicato in quanto si tratta di dettagli specifici nel framework Volley. La domanda SO referenziata se riguarda l'uso della HttpClientclasse.
Michael Banzon,

Risposte:


359

Vedere Request.setRetryPolicy()e il costruttore per DefaultRetryPolicy, ad es

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));

Sai anche come impostare la priorità di una richiesta?
Markus,

2
@Markus ignora Request.getPriority () per restituire qualcosa oltre a 'normale'. ImageRequest fa questo. NOTA: dovresti chiederlo in una domanda SO separata.
larham1

1
Questo è esattamente quello che stavo cercando per impedire a Volley di scartare la mia richiesta che richiede 15 secondi. - Grazie!
slott

Ho appena aggiunto questo per le richieste POST per disabilitare il tentativo di timeout. È incredibilmente sbagliato che gli sviluppatori di Google abbiano deciso di impostare una politica di nuovo tentativo sulle richieste POST. Risolto il mio problema Grazie.
Proverbio

1
@ Roon13 vedi il costruttore della richiesta di esempio che è stato appena aggiunto.
larham1,

226

Per gestire Android Volley Timeout devi usare RetryPolicy

RetryPolicy

  • Volley offre un modo semplice per implementare RetryPolicy per le tue richieste.
  • Volley imposta Presa e connessione predefinite fino a 5 secondi per tutte le richieste.

RetryPolicy è un'interfaccia in cui è necessario implementare la logica di come si desidera riprovare una particolare richiesta quando si verifica un timeout.

Si occupa di questi tre parametri

  • Timeout: specifica il timeout del socket in millis per ogni tentativo di tentativo.
  • Numero di tentativi: numero di tentativi di ripetizione del tentativo.
  • Moltiplicatore di back off: un moltiplicatore utilizzato per determinare il tempo esponenziale impostato su socket per ogni tentativo di tentativo.

Per es. Se RetryPolicy viene creato con questi valori

Timeout - 3000 ms, Numero di tentativi di tentativo - 2, Moltiplicatore di back off - 2.0

Riprova tentativo 1:

  • time = time + (time * Moltiplicatore di back off);
  • tempo = 3000 + 6000 = 9000ms
  • Timeout socket = tempo;
  • Richiesta spedita con timeout socket di 9 secondi

Riprova tentativo 2:

  • time = time + (time * Moltiplicatore di back off);
  • tempo = 9000 + 18000 = 27000ms
  • Timeout socket = tempo;
  • Richiesta spedita con timeout socket di 27 secondi

Quindi, alla fine del tentativo di tentativo 2, se si verifica ancora il timeout del socket, Volley lancerebbe un TimeoutErrorgestore di risposta agli errori dell'interfaccia utente.

//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));

Grazie per una risposta dettagliata su cosa RetryPolicyfa effettivamente l' implementazione.
dbm

5
Bella risposta @Yakiv Mospan. Ma sul tuo esempio, il tempo del primo tentativo è 0 + (3000 * 2) invece di 3000 + (3000 * 2). E il secondo 6000 + (3000 * 2).
13KZ

13KZ, credo che tu abbia ancora torto riguardo ai calcoli del tempo, vedi la mia modifica e verifica contro la fonte di pallavolo
Protongun

1
Solo un promemoria per le persone che lo usano: usa semprenew DefaultRetryPolicy( e assicurati di non riutilizzare mai un RetryPolicyoggetto, poiché l'oggetto viene referenziato durante tutto il processo di richiesta e gli incrementi dei tentativi vengono aggiunti sullo stesso valore di timeout dell'oggetto, facendo in modo che i futuri timeout della richiesta crescano all'infinito
IG Pascual,

come è il timeout della stretta di mano della connessione?
GMsoF,

23

Solo per contribuire con il mio approccio. Come già risposto, RetryPolicyè la strada da percorrere. Ma se hai bisogno di un criterio diverso da quello predefinito per tutte le tue richieste, puoi impostarlo in una classe Request di base, quindi non è necessario impostare il criterio per tutte le istanze delle tue richieste.

Qualcosa come questo:

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

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

Nel mio caso ho un GsonRequest che si estende da questo BaseRequest, quindi non corro il rischio di dimenticare di impostare il criterio per una richiesta specifica e puoi ancora sostituirlo se qualche richiesta specifica lo richiede.


1
Questo dovrebbe funzionare giusto? setRetryPolicy (nuovo 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);
}

7
req.setRetryPolicy(new DefaultRetryPolicy(
    MY_SOCKET_TIMEOUT_MS, 
    DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

Puoi impostarlo MY_SOCKET_TIMEOUT_MScome 100. Qualunque cosa tu voglia impostare questo è in millisecondi. DEFAULT_MAX_RETRIESpuò essere 0 il valore predefinito è 1.


4
int MY_SOCKET_TIMEOUT_MS=500;

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

3

Un altro modo per farlo è in JsonObjectRequest personalizzato di:

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

Fonte: Esempio Volley Android


2

Soluzione alternativa se tutte le soluzioni di cui sopra non funzionano per te

Per impostazione predefinita, Volley imposta il timeout equamente per entrambi setConnectionTimeout()e setReadTimeout()con il valore da RetryPolicy. Nel mio caso, Volleygenera un'eccezione di timeout per grandi blocchi di dati, vedere:

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

La mia soluzione è creare una classe che si estende HttpStackcon la mia setReadTimeout()politica. Quindi usalo quando crea RequestQueuecome segue:

Volley.newRequestQueue(mContext.getApplicationContext(), new MyHurlStack())

1

Ho finito per aggiungere un metodo setCurrentTimeout(int timeout)a RetryPolicye la sua implementazione in DefaultRetryPolicy.

Quindi ho aggiunto un setCurrentTimeout(int timeout)nella classe Request e l'ho chiamato.

Questo sembra fare il lavoro.

Mi dispiace per la mia pigrizia a proposito e evviva per l'open source.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.