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

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

Я пробовал добавить этот код:

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

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

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


person Cissmayazz    schedule 13.06.2013    source источник
comment
Возможный дубликат: stackoverflow.com/questions/693997/   -  person Adam Stelmaszczyk    schedule 13.06.2013
comment
@AdamStelmaszczyk - это не будет дубликатом, поскольку речь идет о конкретных деталях в структуре Volley. Упомянутый вопрос SO, если об использовании класса HttpClient.   -  person Michael Banzon    schedule 13.06.2013


Ответы (7)


См. 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));
person larham1    schedule 18.06.2013
comment
Вы также знаете, как установить приоритет запроса? - person Markus; 19.06.2013
comment
@Markus переопределяет Request.getPriority (), чтобы вернуть что-то помимо «нормального». ImageRequest делает это. ПРИМЕЧАНИЕ: вы должны задать этот вопрос в отдельном SO-вопросе. - person larham1; 20.06.2013
comment
Это именно то, что я искал, чтобы Volley не отклонил мой запрос, который занимает 15 секунд. - Спасибо! - person slott; 03.11.2013
comment
Я просто добавил это для запросов POST, чтобы отключить повторную попытку по таймауту. Это невероятно неправильно, что разработчики Google решили установить политику повтора для запросов POST. Решил мою проблему. Спасибо. - person Proverbio; 01.10.2014
comment
@ larham1 где мне писать конструктор DefaultRetryPolicy? Volley.jar состоит из скомпилированных классов. мы не можем редактировать этот Request.class, верно? - person Roon13; 15.05.2015
comment
@ Roon13 см. Только что добавленный пример конструктора запроса. - person larham1; 16.05.2015
comment
Как я могу сделать такое изменение, чтобы оно использовалось во всех запросах. Есть ли способ переопределить метод добавления requestQueue, чтобы все запросы использовали одну и ту же измененную политику повторных попыток? - person Kumar Deepak; 08.03.2016
comment
@KumarDeepak Вы должны создать подкласс *Request и установить там политику повтора. См. ответ Андроидерсона - person Andrew T.; 11.03.2016

Чтобы обработать тайм-аут Android Volley Timeout, вам необходимо использовать RetryPolicy

RetryPolicy

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

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

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

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

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

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

Повторная попытка 1:

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

Повторная попытка 2:

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

Таким образом, в конце повторной попытки 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));
person Yakiv Mospan    schedule 04.03.2014
comment
Спасибо за подробный ответ о том, что на самом деле делает реализация RetryPolicy. - person dbm; 20.11.2014
comment
Хороший ответ @Yakiv Mospan, но на вашем примере время первой попытки 0 + (3000 * 2) вместо 3000 + (3000 * 2). И второй 6000+ (3000 * 2). - person 13KZ; 02.01.2015
comment
13KZ, я считаю, что вы все еще ошибаетесь в отношении расчетов времени, посмотрите мою правку и сверьте с источником залпа - person Protongun; 30.06.2016
comment
Просто напоминание для людей, использующих это: всегда используйте new DefaultRetryPolicy( и убедитесь, что никогда не используйте повторно объект RetryPolicy, так как на объект ссылаются на протяжении всего процесса запроса, а приращения повторения добавлен к тому же значению тайм-аута объекта, таким образом увеличивая время ожидания ваших будущих запросов бесконечно - person I.G. Pascual; 28.11.2016
comment
как тайм-аут подтверждения соединения? - person Sam YC; 03.01.2017
comment
формула Back Off Multiplier спасет мою жизнь. Я ошибся. - person Sam YC; 25.01.2017

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

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

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

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

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

person Androiderson    schedule 07.10.2013
comment
Это должно работать правильно? setRetryPolicy (новый DefaultRetryPolicy (1000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); - person LOG_TAG; 05.02.2015

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.

person Manasvi    schedule 07.03.2018

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

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

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

person KnowIT    schedule 06.02.2015

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

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

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

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

Volley.newRequestQueue(mContext.getApplicationContext(), new MyHurlStack())
person Bao Le    schedule 11.11.2014

В итоге я добавил метод setCurrentTimeout(int timeout) в RetryPolicy и его реализацию в DefaultRetryPolicy.

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

Кажется, это работает.

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

person Cissmayazz    schedule 13.06.2013