Volley – solicitud de http en bloqueo

Estoy aprendiendo a usar Google Volley en estos días. Es muy conveniente para una conexión rápida. Parece que todas las solicitudes se están ejecutando en el fondo en Volley. Por ejemplo:

volleyRequestQueue.add(new JsonObjectRequest(Method.POST, SIGNUP_URL, reqBody, new SignUpResponseListener(), new MyErrorListener())); 

Utilizando el código anterior, podemos realizar una llamada POST que se ejecuta en segundo plano (modo no bloqueante). Ahora mi pregunta es: ¿Es posible hacer la llamada POST de la manera de bloqueo? ¿Por qué necesito una forma de bloqueo para hacer una llamada REST? Debido a que algunas llamadas, como iniciar sesión, deben hacerse antes de hacer otra cosa.

Gracias

Volley admite la solicitud de bloqueo a través de RequestFutures. Crear una solicitud normal, pero establecer sus devoluciones de llamada como su futuro solicitud, que es sólo la extensión de volley de un estándar java futuros. La llamada a future.get () bloqueará.

Parece algo como esto

 RequestFuture<JSONObject> future = RequestFuture.newFuture(); JsonObjectRequest request = new JsonObjectRequest(Method.POST, SIGNUP_URL, reqBody, future, future) volleyRequestQueue.add(request); try { JSONObject response = future.get(); } catch (InterruptedException e) { } catch (ExecutionException e) { } 

Aquí está una respuesta más clara que maneja InterruptedException correctamente así como tiempo de espera. Tenga en cuenta que la única vez que desearía tragar la interrupción y continuar es si específicamente desea utilizar la interrupción para cancelar la respuesta a la solicitud.

 RequestFuture<JSONObject> future = RequestFuture.newFuture(); JsonObjectRequest request = new JsonObjectRequest(Method.POST, SIGNUP_URL, reqBody, future, future); volleyRequestQueue.add(request); try { JSONObject response = null; while (response == null) { try { response = future.get(30, TimeUnit.SECONDS); // Block thread, waiting for response, timeout after 30 seconds } catch (InterruptedException e) { // Received interrupt signal, but still don't have response // Restore thread's interrupted status to use higher up on the call stack Thread.currentThread().interrupt(); // Continue waiting for response (unless you specifically intend to use the interrupt to cancel your request) } } // Do something with response, ie new SignUpResponseListener().onResponse(response); } catch (ExecutionException e) { // Do something with error, ie new MyErrorListener().onErrorResponse(new VolleyError(e)); } catch (TimeoutException e) { // Do something with timeout, ie new MyErrorListener().onErrorResponse(new VolleyError(e)); } 

Si desea hacer algo exactamente después de la solicitud Volley, utilice un listener callback onSuccess (SignUpResponseListener en ese caso) y coloque el código allí. Esta es la mejor práctica.

Quiero añadir algo a la respuesta de Gabriel. Mientras que RequestFuture bloquea el subproceso del que se llama y sirve a su propósito, la solicitud de red en sí no se lleva a cabo en ese hilo. En su lugar, se lleva a cabo en un hilo de fondo.

Por lo que entiendo después de pasar por la biblioteca, las solicitudes en el RequestQueue se despachan en su método start() :

  public void start() { .... mCacheDispatcher = new CacheDispatcher(...); mCacheDispatcher.start(); .... NetworkDispatcher networkDispatcher = new NetworkDispatcher(...); networkDispatcher.start(); .... } 

Ahora las clases de CacheDispatcher y NetworkDispatcher extienden el hilo. Tan eficazmente se genera un nuevo subproceso de trabajo para deshacer la cola de solicitudes y la respuesta se devuelve a los oyentes de éxito y error implementados internamente por RequestFuture .

Así que no veo ningún punto en hacer un hilo de bloqueo separado para usar RequestFuture . En lugar de lo que Makibo mencionó en su respuesta – "utilizar un oyente de llamada de retorno onSuccess (SignUpResponseListener en ese caso) y poner el código allí."

No podría conseguir el trabajo de RequestFuture así que apenas utilicé un oyente de la llamada de vuelta como Makibo sugirió. No tengo ni idea de por qué fue downvoted, esta es probablemente la mejor solución para el problema común original de diferentes solicitudes Volley que todo depende de un inicio de sesión o algo. En este ejemplo, quiero subir una foto, pero primero tengo que comprobar si el usuario está conectado o no. Si no, tengo que iniciar sesión y luego esperar el éxito antes de subir la foto. Si ya has iniciado sesión, sólo tienes que ir directamente a subir la foto.

Aquí está mi código de ejemplo:

 // interface we'll use for listener public interface OnLoginListener { public void onLogin(); } public void uploadPhoto(final String username, final String password, final String photo_location) { // first setup callback listener that will be called if/when user is logged in OnLoginListener onLoginListener=new OnLoginListener() { @Override public void onLogin() { uploadPhotoLoggedIn(photo_location); } }; // simplistic already logged in check for this example, just checking if username is null if (loggedInUsername==null) { // if it null, login and pass listener httpLogin(username, password, onLoginListener); } else { // if not null, already logged in so just call listener method onLoginListener.onLogin(); } } public void httpLogin(String username, String password, final OnLoginListener onLoginListener) { StringRequest loginRequest = new StringRequest(Request.Method.POST, "https://www.example.com/login.php", new Response.Listener<String>() { @Override public void onResponse(String txtResponse) { Log.d("STACKOVERFLOW",txtResponse); // call method of listener after login is successful. so uploadPhotoLoggedIn will be called now onLoginListener.onLogin(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // TODO Auto-generated method stub Log.d("VOLLEYERROR","error => "+error.toString()); } } ) { }; // Just getting the Volley request queue from my application class (GetApplicatio.java), and adding request GetApplication.getRequestQueue().add(loginRequest); } 
  • No se puede tomar el progreso en la carga de archivos POST HTTP (Android)
  • ¿La intención de Android de publicar la URL?
  • Error al ejecutar el mensaje Http en panal
  • De todos modos para capturar datos de formulario a través del método POST en Android WebView?
  • Cómo agregar parámetros a HttpURLConnection mediante POST
  • HttpURLConnection Post: El flujo de salida no tiene efecto?
  • Android: comprueba si la solicitud es GET o POST
  • Publicar un servicio JSONArray en WCF desde android
  • Solicitud de publicación de Android en IOS
  • Enviar array php con POST android
  • ¿Cómo puedo cambiar CONTENT-TYPE de WebView # PostUrl ()?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.