Зміна тривалості очікування волейболу


191

Я використовую нову рамку Volley для Android, щоб зробити запит на свій сервер. Але це час очікування, перш ніж отримати відповідь, хоча він реагує.

Я спробував додати цей код:

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

в HttpClientStackрамках Воллі з іншим цілим числом (50000), але воно все-таки закінчується до 50 секунд.

Чи є спосіб змінити час очікування на довге значення?



21
@AdamStelmaszczyk - це не буде дублікатом, оскільки йдеться про конкретні деталі в рамках Воллі. Посилання на питання 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 робить це. ПРИМІТКА. Ви повинні задавати це питання окремим запитанням про так.
— larham1

1
Це саме те, що я шукав, щоб запобігти відхилення Воллі мого запиту, який займає 15 секунд. - Дякую!
— слот

Я щойно додав це для запитів POST, щоб вимкнути повторний час у режимі очікування. Неймовірно неправильно, що розробники Google вирішили встановити повторну політику для запитів POST. Вирішили мою проблему. Дякую.
— Proverbio

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:

  • time = time + (час * Back Multiplier);
  • час = 3000 + 6000 = 9000мс
  • Socket Timeout = час;
  • Запит відправлений із розеткою з розеткою 9 сек

Повторна спроба 2:

  • time = time + (час * Back Multiplier);
  • час = 9000 + 18000 = 27000мс
  • Socket Timeout = час;
  • Запит відправлений з розеткою з розеткою 27 сек

Отже, наприкінці спроби 2 спроби повторно, якщо все-таки відбудеться час вимкнення Socket, Воллі закине 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реально робить реалізація.
— dbm

5
Приємна відповідь @Yakiv Mospan. Але у вашому прикладі час першої спроби 0 + (3000 * 2) замість 3000 + (3000 * 2). А другий 6000 + (3000 * 2).
— 13KZ

13 КЗ, я вважаю, що ви все ще помиляєтесь щодо розрахунків часу, дивіться мою редагування та підтверджуйте проти джерела залпу
— Protongun

1
Просто нагадування для людей , що використовують це: завжди використовувати new DefaultRetryPolicy(і переконайтеся , що ніколи не використовувати повторно в RetryPolicyоб'єкт, а об'єкт посилається через весь процес запиту та збільшення повторів додають в протягом того ж значення об'єкта тайм - аут, що робить ваші майбутні інтервали часу запиту рости нескінченно
— IG Pascual

як відбувається таймаут рукостискання підключення?
— 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)класу "Запит" і зателефонував.

Це, здається, робить свою роботу.

Вибачте за мою лінь, до речі, і ура за відкритий код.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.