Ändern Sie die Volley-Timeout-Dauer

190

Ich verwende das neue Volley-Framework für Android, um eine Anfrage an meinen Server zu senden. Es tritt jedoch eine Zeitüberschreitung auf, bevor die Antwort angezeigt wird, obwohl dies der Fall ist.

Ich habe versucht, diesen Code hinzuzufügen:

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

in HttpClientStackdes Volley-Frameworks zu einer anderen Ganzzahl (50000), aber es läuft immer noch vor 50 Sekunden ab.

Gibt es eine Möglichkeit, das Zeitlimit auf einen langen Wert zu ändern?

Cissmayazz
quelle
Mögliches Duplikat: stackoverflow.com/questions/693997/…
Adam Stelmaszczyk
21
@AdamStelmaszczyk - Dies wäre kein Duplikat, da es sich um bestimmte Details im Volley-Framework handelt. Die referenzierte SO-Frage bezieht sich auf die Verwendung der HttpClientKlasse.
Michael Banzon

Antworten:

357

Siehe Request.setRetryPolicy()und den Konstruktor für DefaultRetryPolicyz

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
quelle
Wissen Sie auch, wie Sie die Priorität einer Anfrage festlegen?
Markus
2
@ Markus überschreibt Request.getPriority (), um etwas anderes als "normal" zurückzugeben. ImageRequest macht das. HINWEIS: Sie sollten dies in einer separaten SO-Frage stellen.
Larham1
1
Dies ist genau das, wonach ich gesucht habe, um zu verhindern, dass Volley meine Anfrage verwirft, was 15 Sekunden dauert. - Danke!
Slott
Ich habe dies nur für POST-Anforderungen hinzugefügt, um die Wiederholung bei Zeitüberschreitung zu deaktivieren. Es ist unglaublich falsch, dass Google-Entwickler beschlossen haben, eine Wiederholungsrichtlinie für POST-Anfragen festzulegen. Mein Problem wurde gelöst. Vielen Dank.
Sprichwort
1
@ Roon13 siehe den gerade hinzugefügten Beispielanforderungskonstruktor.
Larham1
226

Um mit Android Volley Timeout umzugehen, müssen Sie verwenden RetryPolicy

RetryPolicy

  • Volley bietet eine einfache Möglichkeit, Ihre RetryPolicy für Ihre Anforderungen zu implementieren.
  • Volley setzt den Standardwert für Socket & ConnectionTImeout für alle Anforderungen auf 5 Sekunden.

RetryPolicy ist eine Schnittstelle, in der Sie Ihre Logik implementieren müssen, wie Sie eine bestimmte Anforderung wiederholen möchten, wenn eine Zeitüberschreitung auftritt.

Es befasst sich mit diesen drei Parametern

  • Timeout - Gibt das Socket-Timeout in Millis pro Wiederholungsversuch an.
  • Anzahl der Wiederholungen - Häufigkeit, mit der erneut versucht wird.
  • Back Off Multiplikator - Ein Multiplikator, der verwendet wird, um die exponentielle Zeit zu bestimmen, die für jeden Wiederholungsversuch auf Socket eingestellt ist.

Zum Beispiel. Wenn RetryPolicy mit diesen Werten erstellt wird

Zeitüberschreitung - 3000 ms, Anzahl der Wiederholungsversuche - 2, Back-Off-Multiplikator - 2,0

Wiederholungsversuch 1:

  • Zeit = Zeit + (Zeit * Back Off Multiplikator);
  • Zeit = 3000 + 6000 = 9000 ms
  • Socket Timeout = Zeit;
  • Anfrage mit Socket Timeout von 9 Sekunden versandt

Wiederholungsversuch 2:

  • Zeit = Zeit + (Zeit * Back Off Multiplikator);
  • Zeit = 9000 + 18000 = 27000 ms
  • Socket Timeout = Zeit;
  • Anfrage mit Socket Timeout von 27 Sekunden versandt

Wenn also am Ende von Wiederholungsversuch 2 immer noch ein Socket-Timeout auftritt, wirft Volley einen TimeoutErrorFehlerbehandlungs-Handler für die Benutzeroberfläche.

//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
quelle
Vielen Dank für eine ausführliche Antwort darauf, was die RetryPolicyImplementierung tatsächlich tut.
DBM
5
Schöne Antwort @Yakiv Mospan. Aber in Ihrem Beispiel ist die Zeit des ersten Versuchs 0 + (3000 * 2) anstelle von 3000 + (3000 * 2). Und der zweite 6000 + (3000 * 2).
13KZ
13KZ, ich glaube, Sie sind immer noch falsch in Bezug auf Zeitberechnungen, sehen Sie meine Bearbeitung und überprüfen Sie gegen die Volley-Quelle
Protongun
1
Nur eine Erinnerung für Leute, die dies verwenden: Verwenden Sie immernew DefaultRetryPolicy( und stellen Sie sicher, dass ein RetryPolicyObjekt niemals wiederverwendet wird, da auf das Objekt während des gesamten Anforderungsprozesses verwiesen wird. Wiederholungsinkremente werden über denselben Objekt-Timeout-Wert hinzugefügt, sodass Ihre zukünftigen Anforderungszeitlimits unendlich wachsen
IG Pascual
Wie ist das Verbindungs-Handshake-Timeout?
GMsoF
23

Nur um mit meinem Ansatz beizutragen. Wie bereits beantwortet, RetryPolicyist der Weg zu gehen. Wenn Sie jedoch für alle Ihre Anforderungen eine andere als die Standardrichtlinie benötigen, können Sie diese in einer Basisanforderungsklasse festlegen, sodass Sie die Richtlinie nicht für alle Instanzen Ihrer Anforderungen festlegen müssen.

Etwas wie das:

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

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

In meinem Fall habe ich eine GsonRequest, die sich von dieser BaseRequest aus erstreckt, sodass ich nicht das Risiko eingehen muss, die Richtlinie für eine bestimmte Anforderung zu vergessen, und Sie können sie trotzdem überschreiben, wenn eine bestimmte Anforderung dies erfordert.

Androiderson
quelle
1
Das sollte richtig funktionieren? setRetryPolicy (neue 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
quelle
7
req.setRetryPolicy(new DefaultRetryPolicy(
    MY_SOCKET_TIMEOUT_MS, 
    DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

Sie können MY_SOCKET_TIMEOUT_MS100 einstellen . Was auch immer Sie einstellen möchten, ist in Millisekunden. DEFAULT_MAX_RETRIESkann 0 sein Standard ist 1.

Manasvi
quelle
4
int MY_SOCKET_TIMEOUT_MS=500;

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

Eine andere Möglichkeit ist die benutzerdefinierte JsonObjectRequest von:

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

Quelle: Android Volley Beispiel

Weiß es
quelle
2

Alternative Lösung, wenn alle oben genannten Lösungen für Sie nicht funktionieren

Standardmäßig hat Volley das Timeout für beide gleichermaßen setConnectionTimeout()und setReadTimeout()mit dem Wert von festgelegt RetryPolicy. In meinem Fall wird eine VolleyTimeout-Ausnahme für große Datenmengen ausgelöst. Siehe:

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

Meine Lösung besteht darin, eine Klasse zu erstellen, die sich HttpStackauf meine eigene setReadTimeout()Richtlinie erstreckt. Verwenden Sie es dann beim Erstellen RequestQueuewie folgt:

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

Ich landete das Hinzufügen einer Methode setCurrentTimeout(int timeout)zu der RetryPolicyund der Umsetzung in DefaultRetryPolicy.

Dann habe ich ein setCurrentTimeout(int timeout)in der Request-Klasse hinzugefügt und es aufgerufen.

Dies scheint den Job zu machen.

Entschuldigung für meine Faulheit übrigens und Hurra für Open Source.

Cissmayazz
quelle