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.