Изменить продолжительность таймаута


191

Я использую новую платформу Volley для Android, чтобы сделать запрос к моему серверу. Но это время ожидания до получения ответа, хотя он и отвечает.

Я попытался добавить этот код:

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

в HttpClientStackструктуре Volley к другому целому числу (50000), но время ожидания истекает до 50 секунд.

Есть ли способ изменить время ожидания на длинное значение?


Возможный дубликат: stackoverflow.com/questions/693997/…
Адам Stelmaszczyk

21
@AdamStelmaszczyk - это не будет дубликатом, поскольку речь идет о конкретных деталях в структуре Volley. Ссылочный вопрос SO об использовании HttpClientкласса.
Майкл Банзон

Ответы:


359

Смотрите Request.setRetryPolicy()и конструктор для DefaultRetryPolicy, например,

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

Вы также знаете, как установить приоритет запроса?
Маркус

2
@Markus переопределяет Request.getPriority (), чтобы вернуть что-то, кроме «нормального». ImageRequest делает это. ПРИМЕЧАНИЕ: вы должны задать это в отдельном вопросе SO.
larham1

1
Это именно то, что я искал, чтобы не дать Волею отменить мой запрос, который занимает 15 секунд. - Спасибо!
Слот

Я только добавил это для запросов POST, чтобы отключить повторную попытку по таймауту. Невероятно неправильно, что разработчики Google решили установить политику повторных попыток для запросов POST. Решил мою проблему. Спасибо.
Пословица

1
@ Roon13 см. Пример конструктора запросов, который был только что добавлен.
larham1

226

Для обработки Android Volley Timeout вам необходимо использовать RetryPolicy

RetryPolicy

  • Volley предоставляет простой способ реализовать RetryPolicy для ваших запросов.
  • Volley устанавливает значение Socket & ConnectionTImeout по умолчанию равным 5 секундам для всех запросов.

RetryPolicy это интерфейс, в котором вам нужно реализовать свою логику того, как вы хотите повторить определенный запрос, когда происходит тайм-аут.

Он имеет дело с этими тремя параметрами

  • Тайм-аут - Указывает время ожидания сокета в миллисах раз за каждую попытку повторной попытки.
  • Количество попыток - количество попыток повторной попытки.
  • Back Off Multiplier - множитель, который используется для определения экспоненциального времени, установленного для сокета, при каждой попытке повтора.

Например Если RetryPolicy создан с этими значениями

Тайм-аут - 3000 мс, количество попыток повторной попытки - 2, множитель отключения - 2,0

Повторите попытку 1:

  • время = время + (время * Back Off Multiplier);
  • время = 3000 + 6000 = 9000 мс
  • Время ожидания сокета = время;
  • Запрос отправлен с Тайм-аутом сокета 9 секунд

Повторите попытку 2:

  • время = время + (время * Back Off Multiplier);
  • время = 9000 + 18000 = 27000 мс
  • Время ожидания сокета = время;
  • Запрос отправлен с тайм-аутом сокета 27 секунд

Таким образом, в конце Retry Attempt 2, если все еще случается тайм-аут сокета, Volley выдавал бы TimeoutErrorобработчик ошибок вашего интерфейса.

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

Спасибо за подробный ответ о том, что на RetryPolicyсамом деле делает реализация.
дБмВт

5
Хороший ответ @Yakiv Mospan. Но на вашем примере время первой попытки 0 + (3000 * 2) вместо 3000 + (3000 * 2). А второй 6000+ (3000 * 2).
13KZ

13KZ, я полагаю, что вы все еще не правы в отношении расчета времени, посмотрите мои изменения и проверьте источник залпа
Protongun

1
Просто напоминание для людей , использующих это: всегда использовать new DefaultRetryPolicy(и убедитесь , что никогда не использовать повторно в RetryPolicyобъект, а объект ссылается через весь процесс запроса и приращения повторов добавляют в течение того же значения объекта тайм - аут, что делает ваши будущие интервалы времени запроса расти бесконечно
И.Г. Паскуаль

как истекает время ожидания соединения?
GMsoF

23

Просто чтобы внести свой вклад с моим подходом. Как уже ответили, RetryPolicyэто путь. Но если вам нужна политика, отличная от политики по умолчанию для всех ваших запросов, вы можете установить ее в базовом классе запросов, поэтому вам не нужно устанавливать политику для всех экземпляров ваших запросов.

Что-то вроде этого:

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

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

В моем случае у меня есть GsonRequest, который выходит из этого BaseRequest, поэтому я не рискую забыть установить политику для конкретного запроса, и вы все равно можете переопределить ее, если этого требует какой-то конкретный запрос.


1
Это должно работать правильно? setRetryPolicy (новый 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));

Вы можете установить MY_SOCKET_TIMEOUT_MSкак 100. Все, что вы хотите установить это в миллисекундах. DEFAULT_MAX_RETRIESможет быть 0 по умолчанию 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

Другой способ сделать это в пользовательском JsonObjectRequest:

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

Источник: Android Volley Пример


2

Альтернативное решение, если все вышеперечисленные решения не работают для вас

По умолчанию Volley устанавливает одинаковое время ожидания для обоих setConnectionTimeout()и setReadTimeout()со значением из RetryPolicy. В моем случае Volleyвыдает исключение тайм-аута для большого блока данных:

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

Мое решение - создать класс, который расширяет HttpStackмою собственную setReadTimeout()политику. Затем используйте его при создании RequestQueueследующим образом:

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

1

Я закончил тем, что добавил метод setCurrentTimeout(int timeout)к RetryPolicyи его реализация в DefaultRetryPolicy.

Затем я добавил setCurrentTimeout(int timeout)в класс Request и вызвал его.

Это похоже на работу.

Извините за мою лень, кстати, и ура за открытый исходный код.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.