Zmień limit czasu Volley


191

Korzystam z nowej struktury Volley dla Androida, aby wysłać żądanie do mojego serwera. Ale upływa limit czasu przed otrzymaniem odpowiedzi, chociaż nie odpowiada.

Próbowałem dodać ten kod:

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

w HttpClientStackstrukturze Volley do innej liczby całkowitej (50000), ale nadal upływa limit czasu przed 50 sekundami.

Czy istnieje sposób na zmianę limitu czasu na długą wartość?



21
@AdamStelmaszczyk - nie byłby to duplikat, ponieważ dotyczy konkretnych szczegółów w ramach Volley. Przywoływane pytanie SO, jeśli chodzi o wykorzystanie HttpClientklasy.
Michael Banzon

Odpowiedzi:


359

Zobacz Request.setRetryPolicy()i konstruktor DefaultRetryPolicynp

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

Czy wiesz także, jak ustawić priorytet żądania?
Markus

2
@ Markus zastępuje Request.getPriority (), aby zwrócić coś oprócz „normalnego”. ImageRequest to robi. UWAGA: powinieneś zadawać to pytanie w osobnym pytaniu SO.
larham1

1
Właśnie tego szukałem, aby Volley nie odrzucił mojej prośby, co zajmuje 15 sekund. - Dzięki!
slott

Właśnie dodałem to dla żądań POST, aby wyłączyć ponawianie próby przekroczenia limitu czasu. To niesamowite, że Programiści Google postanowili ustawić zasady ponawiania żądań POST. Rozwiązałem mój problem. Dzięki.
Przysłowia

1
@ Roon13 zobacz przykładowy konstruktor żądań, który właśnie został dodany.
larham1

226

Aby obsłużyć Android Volley Timeout, musisz użyć RetryPolicy

RetryPolicy

  • Volley zapewnia łatwy sposób zaimplementowania RetryPolicy dla twoich żądań.
  • Volley ustawia domyślne Socket & ConnectionTImeout na 5 sekund dla wszystkich żądań.

RetryPolicy to interfejs, w którym musisz zaimplementować logikę tego, w jaki sposób chcesz ponowić określone żądanie w przypadku przekroczenia limitu czasu.

Zajmuje się tymi trzema parametrami

  • Limit czasu - określa limit czasu gniazda w milisekundach dla każdej ponownej próby.
  • Liczba ponownych prób - liczba prób ponownych prób.
  • Back Off Multiplier - Mnożnik używany do określania wykładniczego czasu ustawionego na gniazdo dla każdej próby ponownej próby.

Np. Jeśli RetryPolicy jest tworzony z tymi wartościami

Limit czasu - 3000 ms, liczba prób ponownych prób - 2, mnożnik wycofania - 2,0

Spróbuj ponownie 1:

  • time = time + (time * Back Off Multiplier);
  • czas = 3000 + 6000 = 9000 ms
  • Limit czasu gniazda = czas;
  • Żądanie wysłane z Limitem czasu gniazda 9 sekund

Spróbuj ponownie 2:

  • time = time + (time * Back Off Multiplier);
  • czas = 9000 + 18000 = 27000 ms
  • Limit czasu gniazda = czas;
  • Żądanie wysłane z Limitem czasu gniazda 27 Sek

Pod koniec próby ponownej próby 2, jeśli nadal występuje limit czasu gniazda, Volley rzuci a TimeoutErrorw moduł obsługi odpowiedzi na błąd interfejsu użytkownika.

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

Dzięki za szczegółową odpowiedź na temat tego, co RetryPolicyfaktycznie robi wdrożenie.
dbm

5
Dobra odpowiedź @ Yakiv Mospan. Ale na twoim przykładzie czas pierwszej próby to 0 + (3000 * 2) zamiast 3000 + (3000 * 2). A drugi 6000 + (3000 * 2).
13KZ

13KZ, uważam, że nadal się mylisz w obliczeniach czasu, zobacz moją edycję i sprawdź w stosunku do źródła siatkówki
Protongun

1
Przypomnienie dla osób korzystających z tego: zawsze używaj obiektu new DefaultRetryPolicy(i pamiętaj, aby nigdy nie używać go ponownieRetryPolicy , ponieważ obiekt jest przywoływany przez cały proces żądania, a przyrosty ponownych prób są dodawane w stosunku do tej samej wartości limitu czasu obiektu, dzięki czemu twoje przyszłe limity czasu oczekiwania rosną nieskończenie
IG Pascual

jaki jest limit czasu uzgadniania połączenia?
GMsoF,

23

Po prostu przyczynić się do mojego podejścia. Jak już odpowiedziano, RetryPolicyjest to najlepsza droga. Ale jeśli potrzebujesz polityki innej niż domyślna dla wszystkich swoich żądań, możesz ustawić ją w podstawowej klasie Żądania, więc nie musisz ustawiać zasad dla wszystkich instancji twoich żądań.

Coś takiego:

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

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

W moim przypadku mam GsonRequest, który rozciąga się od tego BaseRequest, więc nie ryzykuję, że zapomnę ustawić zasady dla konkretnego żądania i nadal możesz je zastąpić, jeśli jakieś konkretne żądanie tego wymaga.


1
To powinno zadziałać, prawda? setRetryPolicy (nowy 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));

Możesz ustawić MY_SOCKET_TIMEOUT_MSjako 100. Cokolwiek chcesz ustawić, to w milisekundach. DEFAULT_MAX_RETRIESmoże być 0 domyślnie jest 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

Innym sposobem na to jest niestandardowe JsonObjectRequest przez:

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

Źródło: Android Volley Example


2

Alternatywne rozwiązanie, jeśli wszystkie powyższe rozwiązania nie działają dla Ciebie

Domyślnie Volley ustawia limit czasu zarówno dla obu, jak setConnectionTimeout()i setReadTimeout()dla wartości z RetryPolicy. W moim przypadku Volleyzgłasza wyjątek limitu czasu dla dużej porcji danych patrz:

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

Moim rozwiązaniem jest stworzenie klasy, która rozszerza się HttpStackz moimi własnymi setReadTimeout()zasadami. Następnie użyj go, gdy tworzy się RequestQueuew następujący sposób:

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

1

Skończyło się na dodanie metody setCurrentTimeout(int timeout)do RetryPolicyi to wdrożenie w DefaultRetryPolicy.

Następnie dodałem a setCurrentTimeout(int timeout)do klasy Request i nazwałem ją.

To chyba działa.

Przy okazji przepraszam za lenistwo i brawo za open source.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.