Android – Volley RequestFuture Timeout
Estoy experimentando un problema al usar la clase RequestFuture de volley. En realidad sólo se detiene en wait(0)
; Dentro de la función doGet()
en la clase RequestFuture a continuación y nunca se despierta por onResponse
o onErrorResponse
como creo que debería.
private synchronized T doGet(Long timeoutMs) throws InterruptedException, ExecutionException, TimeoutException { if (mException != null) { throw new ExecutionException(mException); } if (mResultReceived) { return mResult; } if (timeoutMs == null) { wait(0); } else if (timeoutMs > 0) { wait(timeoutMs); } if (mException != null) { throw new ExecutionException(mException); } if (!mResultReceived) { throw new TimeoutException(); } return mResult; } @Override public boolean isCancelled() { if (mRequest == null) { return false; } return mRequest.isCanceled(); } @Override public synchronized boolean isDone() { return mResultReceived || mException != null || isCancelled(); } @Override public synchronized void onResponse(T response) { mResultReceived = true; mResult = response; notifyAll(); } @Override public synchronized void onErrorResponse(VolleyError error) { mException = error; notifyAll(); }
Esta es la forma en que trato de llamar a todo esto arriba.
- Android Volley almacena peticiones cuando está fuera de línea
- Cómo comunicarse desde php a Android
- ¿Apoya Android varias solicitudes HTTP al mismo tiempo?
- Android envía la solicitud de correos https al servidor sin métodos desaconsejados
- Problema con la solicitud de Facebook en Android
RequestFuture<JSONObject> future = RequestFuture.newFuture(); JsonObjectRequest myReq = new JsonObjectRequest(Request.Method.POST, url, jsonObj, future, future); requestQueue.add(myReq); try { JSONObject response = future.get(); } catch (InterruptedException e) { // handle the error } catch (ExecutionException e) { // handle the error }
También intenté reemplazar la línea
requestQueue.add(myReq);
con
future.setRequest(requestQueue.add(myReq));
o
future.setRequest(myReq);
Que tampoco ayudó.
Ya he probado una solicitud habitual Volley que funcionó muy bien con estos parámetros, por lo que no debería ser la causa. Supongo que el problema es que la solicitud nunca se ejecuta realmente, por lo que los oyentes de respuesta nunca se alcanzan. También intentó requestQueue.start()
, pero no cambió nada.
Espero haber explicado mi problema lo suficientemente bien, gracias de antemano!
- Android Volley hace 2 peticiones al servidor cuando la política de reintento se establece en 0
- Android: comprueba si la solicitud es GET o POST
- Android Volley + JSONObjectRequest Almacenamiento en caché
- Obtención de solicitud de contenido corporal mediante el método POST de Retrofit 2.0
- Android httprequest java.net.UnknownHostException
- Glide - agregar cabecera a la solicitud
- Hacer solicitud de volley en diferentes hilos
- Los anuncios de Google con varios tamaños de anuncio de DFP dan error
La adición de un tiempo de espera al método get dará la capacidad de capturar el error, si no se da tiempo de espera, entonces envía el error de nuevo al subproceso principal. Cambiando JSONObject response = future.get();
Con JSONObject response = future.get(REQUEST_TIMEOUT, TimeUnit.SECONDS);
Debe hacer el truco y envolverlo en un try catch para el tiempo de espera
Resuelto
JSONObject response = future.get ();
Siempre ejecute la solicitud futura en un hilo separado. No funcionará en el hilo principal. Estoy funcionando la llamada futura de la petición en un IntentService y su funcionamiento perfectamente bien.
Codificación feliz
Necesitas llamar a future.get()
en otro hilo. Intente envolverlo en un AsyncTask.
En cuanto a la fuente, parece que RequestQueue
arranca una larga cadena de llamadas para cargar la respuesta y que eventualmente termina en RequestFuture.onResponse
(que a su vez llama a notifyAll
para notificar el hilo para que deje de esperar, como mencionó). Creo que el problema es que wait(0)
y la cadena RequestQueue
ejecutan en el subproceso de interfaz de usuario, por lo que cuando se llama wait(0)
, la cadena RequestQueue
también espera, por lo que onResponse
nunca se llama, por lo que esa línea simplemente cuelga Porque espera (0) espera para siempre).
Además de las soluciones de Blair y Farhan, adjuntar una política de reintento a la solicitud también hace el trabajo.
request.setRetryPolicy(new DefaultRetryPolicy(RETRY_TIME, RETRY_ATTEMPTS, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));