Alterar duração do tempo limite de vôlei

190

Eu uso a nova estrutura do Volley para Android para fazer uma solicitação ao meu servidor. Mas atinge o tempo limite antes de obter a resposta, embora responda.

Eu tentei adicionar este código:

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

no HttpClientStack do quadro Volley para um inteiro diferente (50000), mas ainda vezes antes de 50 segundos.

Existe uma maneira de alterar o tempo limite para um valor longo?

Cissmayazz
fonte
Possível duplicata: stackoverflow.com/questions/693997/…
Adam Stelmaszczyk
21
@AdamStelmaszczyk - isso não seria uma duplicata, pois trata-se de detalhes específicos na estrutura do Volley. A questão SO referenciada se refere ao uso da HttpClientclasse.
Michael Banzon

Respostas:

357

Veja Request.setRetryPolicy()e o construtor para DefaultRetryPolicy, por exemplo

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));
larham1
fonte
Você também sabe como definir a prioridade de uma solicitação?
Markus
2
O @Markus substitui Request.getPriority () para retornar algo além de 'normal'. ImageRequest faz isso. NOTA: você deve fazer isso em uma pergunta SO separada.
larham1
1
Era exatamente isso que eu procurava para impedir que o Volley rejeitasse minha solicitação, que leva 15 segundos. - Thanx!
Slott
Acabei de adicionar isso para solicitações POST para desativar a nova tentativa com tempo limite. É um erro incrível que o Google Developers tenha decidido definir uma política de repetição de solicitações POST. Resolvido meu problema. Obrigado.
Proverbio
1
@ Roon13 veja o construtor de solicitação de amostra que acabou de ser adicionado.
Larham1
226

Para lidar com o Android Volley Timeout, você precisa usar RetryPolicy

RetryPolicy

  • O Volley fornece uma maneira fácil de implementar sua RetryPolicy para suas solicitações.
  • O Volley define o Socket & ConnectionTImeout padrão como 5 segundos para todas as solicitações.

RetryPolicy é uma interface em que você precisa implementar sua lógica de como deseja repetir uma solicitação específica quando ocorrer um tempo limite.

Ele lida com esses três parâmetros

  • Tempo limite - especifica o tempo limite do soquete em milis por cada tentativa de nova tentativa.
  • Número de tentativas - Número de tentativas de repetição.
  • Multiplicador de Desvio - Um multiplicador usado para determinar o tempo exponencial definido como soquete para cada tentativa de repetição.

Por ex. Se RetryPolicy for criado com esses valores

Tempo limite - 3000 ms, Número de tentativas de repetição - 2, Multiplicador de retirada - 2,0

Tente novamente a tentativa 1:

  • time = time + (hora * Multiplicador de recuo);
  • tempo = 3000 + 6000 = 9000ms
  • Tempo limite do soquete = tempo;
  • Pedido enviado com tempo limite de soquete de 9 segundos

Tente novamente a tentativa 2:

  • time = time + (hora * Multiplicador de recuo);
  • tempo = 9000 + 18000 = 27000ms
  • Tempo limite do soquete = tempo;
  • Pedido enviado com tempo limite de soquete de 27 segundos

Portanto, no final da Tentativa de Repetição 2, se o Tempo Limite do Soquete ainda ocorrer, o Volley lançaria um TimeoutErrorno seu manipulador de resposta de Erro de UI.

//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));
Yakiv Mospan
fonte
Obrigado por uma resposta detalhada sobre o que a RetryPolicyimplementação realmente faz.
dbm
5
Resposta agradável @Yakiv Mospan.Mas no seu exemplo, o tempo da primeira tentativa é 0 + (3000 * 2) em vez de 3000 + (3000 * 2). E o segundo 6000 + (3000 * 2).
13KZ 01/01
13KZ, eu acredito que você ainda está errado sobre cálculos de tempo, ver a minha edição e verificar contra a fonte de vôlei
Protongun
1
Apenas um lembrete para as pessoas que usam isso: sempre use new DefaultRetryPolicy(e certifique-se de nunca reutilizar um RetryPolicyobjeto, pois o objeto é referenciado por todo o processo de solicitação, e os incrementos de nova tentativa são adicionados sobre o mesmo valor de tempo limite do objeto, fazendo com que seus futuros tempos limite de solicitação cresçam infinitamente
IG Pascual
como está o tempo limite do handshake de conexão?
GMsoF 3/17/17
23

Apenas para contribuir com a minha abordagem. Como já respondido, RetryPolicyé o caminho a percorrer. Mas se você precisar de uma política diferente do padrão para todas as suas solicitações, poderá defini-la em uma classe Request básica, para que não precise definir a política para todas as instâncias de suas solicitações.

Algo assim:

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

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

No meu caso, eu tenho um GsonRequest que se estende a partir deste BaseRequest, portanto não corro o risco de esquecer de definir a política para uma solicitação específica e você ainda pode substituí-la se alguma solicitação específica exigir.

Androiderson
fonte
1
Isso deve funcionar certo? setRetryPolicy (novo 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);
}
chavanNil
fonte
7
req.setRetryPolicy(new DefaultRetryPolicy(
    MY_SOCKET_TIMEOUT_MS, 
    DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

Você pode definir MY_SOCKET_TIMEOUT_MScomo 100. O que você deseja definir é em milissegundos. DEFAULT_MAX_RETRIESpode ser 0 o padrão é 1.

Manasvi
fonte
4
int MY_SOCKET_TIMEOUT_MS=500;

 stringRequest.setRetryPolicy(new DefaultRetryPolicy(
                MY_SOCKET_TIMEOUT_MS,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Avinash
fonte
3

Outra maneira de fazer isso é no JsonObjectRequest personalizado por:

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

Fonte: Exemplo do Android Volley

Sei
fonte
2

Solução alternativa se todas as soluções acima não estiverem funcionando para você

Por padrão, o Volley define o tempo limite igualmente para ambos setConnectionTimeout()e setReadTimeout()com o valor de RetryPolicy. No meu caso, Volleylança exceção de tempo limite para grandes blocos de dados, consulte:

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

Minha solução é criar uma classe que se estende HttpStackà minha própria setReadTimeout()política. Em seguida, use-o quando criar da RequestQueueseguinte maneira:

Volley.newRequestQueue(mContext.getApplicationContext(), new MyHurlStack())
Bao Le
fonte
1

Acabei adicionando um método setCurrentTimeout(int timeout)ao RetryPolicye sua implementação no DefaultRetryPolicy.

Em seguida, adicionei um setCurrentTimeout(int timeout)na classe Request e o chamei.

Isso parece fazer o trabalho.

Desculpem a minha preguiça, a propósito e viva o código aberto.

Cissmayazz
fonte