Library volley for android does not wait for server response

1

I am new programming on Android and I am trying to create a simple application to do a GET cosulta to my server and to return a text string of just 3 or 4 characters.

For this I use the Volley library that they say is very simple to use.

What I do is the following:

I create a text string: url=" link " and I send it via volley with the following code:

public String hacerGet(String url) {        

    // Instantiate the RequestQueue.

    scode = null; //scode es un String definido en la cabecera

    RequestQueue queue = Volley.newRequestQueue(this);


    // Request a string response from the provided URL.
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    if (response == "") scode = "Sin respuesta";
                    else scode = response;
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            //scode = "Error";
            //errServidor = error.getMessage();
            scode = error.getMessage();
        }

    });

    stringRequest.setRetryPolicy(new DefaultRetryPolicy(5000, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 
    queue.add(stringRequest);


    return scode;
}

The code works fine, it makes the request correctly.

Now, the problem: the line stringRequest.setRetryPolicy (...) is supposed to wait 5s to receive a response from the server. Well, it does not work. Always returns scode = null. The code that calls this function doGet (url) I have it on a button. I press the button and in a few tenths of a second I have Null's answer, when I'm supposed to wait 5s for the server to respond.

I do not know what to do, any help?

Greetings to the forum.

    
asked by AngelF 21.11.2017 в 19:00
source

2 answers

1

The code you are using is asynchronous:

// Request a string response from the provided URL.

StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                //LA RESPUESTA LA OBTIENES AQUI
                if (response == "") scode = "Sin respuesta";
                else scode = response;
            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        //AQUI SI ES QUE HAY ERROR
        //scode = "Error";
        //errServidor = error.getMessage();
        scode = error.getMessage();
    }

});

// AQUI NO OBTENDRAS LA RESPUESTA, ASI QUE NO PUEDES RETORNAR NADA

You could use interfaces to solve your problem, in which your interface would respond within onResponse.

Finally, if you still want to continue doing it with StringRequest and synchronously, try this:

final RequestQueue queue = Volley.newRequestQueue(this);
final CountDownLatch countDownLatch = new CountDownLatch(1);
final Object[] responseHolder = new Object[1];

final StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        responseHolder[0] = response;
        countDownLatch.countDown();
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        responseHolder[0] = error;
        countDownLatch.countDown();
    }
});
queue.add(stringRequest);
try {
    countDownLatch.await();
} catch (InterruptedException e) {
    throw new RuntimeException(e);
}
if (responseHolder[0] instanceof VolleyError) {
    final VolleyError volleyError = (VolleyError) responseHolder[0];
    scode = volleyError.getMessage();
} else {
    final String response = (String) responseHolder[0];
    if (response == "") scode = "Sin respuesta";
                    else scode = response;
}

UPDATE (USING INTERFACE)

        public class MainActivity extends AppCompatActivity {

            private TextView lblMensajes;
            private Button btnGet;


            @Override
            protected void onCreate(Bundle savedInstanceState) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                //textview para ver los mensajes
                final TextView lblMensajes = (TextView) findViewById(R.id.lblMensajes);

                //botón
                final Button btnGet = (Button) findViewById(R.id.btnGet);

                //imageview para mostrar un punto verde o rojo según la respuesta del servidor
                final ImageView ivOk = (ImageView) findViewById(R.id.ivOk);


                ivOk.setVisibility(View.INVISIBLE); //no muestro imagen


                btnGet.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View arg0) {

                        int icanal = 0;


                            String url = hazYManda(icanal);

                            hacerGet(url, new DataResponseListener(){

                                 @Override
                                 public void onResponseData(String codigo){
                                                                         //tratamiento codigo recibido
                                        if (codigo == null) {//si el código recibido es null

                                            //imagen de un triangulo amarillo
                                            ivOk.setImageResource(R.drawable.alert);
                                            //muestro la imagen
                                            ivOk.setVisibility(View.VISIBLE);

                                            lblMensajes.setText("Sin respuesta del servidor\nIntentelo de nuevo");
                                        } else {
                                            //si recibo <0> es que ha ido todo bien
                                            if (codigo.contains("<0>")){
                                                ivOk.setImageResource(R.drawable.ok);
                                                lblMensajes.setText("Todo correcto");
                                            }
                                            else {
                                                //si no es <0> ha habido alguna incidencia
                                                //imagen de un punto rojo
                                                ivOk.setImageResource(R.drawable.cancel);
                                                lblMensajes.setText("Ha habido alguna incidencia");
                                            }

                                            ivOk.setVisibility(View.VISIBLE);                        

                                        }

                                 }

                             }); 


                            //me espero 5 segundos para que no se pulse el botón rápidamente (desactivo el botón durante 5 s)
                            final long esperaTime = 5000L; //se espera 5s
                            btnGet.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    lblMensajes.setBackgroundColor(Color.parseColor("#0099CC"));
                                    lblMensajes.setTextColor(Color.parseColor("#FFFFFF"));

                                    btnGet.setEnabled(true);
                                    lblMensajes.setText("Pulsa el botón");

                                    //ivNo.setVisibility(View.INVISIBLE);
                                    ivOk.setVisibility(View.INVISIBLE);
                                    //ivAlerta.setVisibility(View.INVISIBLE);
                                }
                            }, esperaTime);

                        }           


                    }
                });




            }


            public String hazYManda(int ipu) {
                //Esta función construye una cadena y con ella hace un GET a mi servidor.

                //Este es un ejemplo simplificado. Con la cadena recibida vía GET, el servidor
                //hace unas cuantas consultas a una base de datos MySQL y según el resultado de esas consultas
                //devuelve una cadena que es "<0>" si va todo bien o, en caso contrario, <1> o <2> según la incidencia

                //construyo la cadena ABCD:1
                String scadena = "ABCD:";
                scadena += Integer.toString(ipu);

                //construyo la cadena para hacer GET
                String xurl = "http://miservidor/fichero.php?key=" + scadena;


                return xurl;

            }




            public void hacerGet(String url, final DataResponseListener mListener) {

                scode = null;
                RequestQueue queue = Volley.newRequestQueue(this);

                // Request a string response from the provided URL.
                StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                        new Response.Listener<String>() {
                            @Override
                            public void onResponse(String response) {
                                if (response == "") scode = "Sin respuesta";
                                else scode = response;
                                if (mListener != null){
                                    mListener.onResponseData(scode);
                                }
                            }
                        }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        //scode = "Error";
                        //errServidor = error.getMessage();
                        scode = error.getMessage();
                        if (mListener != null){
                                    mListener.onResponseData(scode);
                                }
                    }

                });

                queue.add(stringRequest);
            }


            public interface DataResponseListener {
                void onResponseData(String data);
            }




        }
    
answered by 21.11.2017 в 19:13
0

Ok, diegoveloper, I'll expand you info. I have simplified the code to make it as clear as possible. Basically, what I do is build a chain and send it via GET to my server. With that string, the server makes a series of queries to a Mysql DB and returns a value of . if everything goes well or , < 2 > if there is any incidence. In tests performed from the Firefox browser, these queries take a couple of seconds at most, before responding, but they are not immediate. The code:

    package xxx.httpget004;

import ...


public class MainActivity extends AppCompatActivity {

    private TextView lblMensajes;
    private Button btnGet;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //textview para ver los mensajes
        final TextView lblMensajes = (TextView) findViewById(R.id.lblMensajes);

        //botón
        final Button btnGet = (Button) findViewById(R.id.btnGet);

        //imageview para mostrar un punto verde o rojo según la respuesta del servidor
        final ImageView ivOk = (ImageView) findViewById(R.id.ivOk);


        ivOk.setVisibility(View.INVISIBLE); //no muestro imagen


        btnGet.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {

                int icanal = 0;


                    codigo = hazYManda(icanal);

                    //tratamiento codigo recibido
                    if (codigo == null) {//si el código recibido es null

                        //imagen de un triangulo amarillo
                        ivOk.setImageResource(R.drawable.alert);
                        //muestro la imagen
                        ivOk.setVisibility(View.VISIBLE);

                        lblMensajes.setText("Sin respuesta del servidor\nIntentelo de nuevo");
                    } else {
                        //si recibo <0> es que ha ido todo bien
                        if (codigo.contains("<0>")){
                            ivOk.setImageResource(R.drawable.ok);
                            lblMensajes.setText("Todo correcto");
                        }
                        else {
                            //si no es <0> ha habido alguna incidencia
                            //imagen de un punto rojo
                            ivOk.setImageResource(R.drawable.cancel);
                            lblMensajes.setText("Ha habido alguna incidencia");
                        }

                        ivOk.setVisibility(View.VISIBLE);                        

                    }


                    //me espero 5 segundos para que no se pulse el botón rápidamente (desactivo el botón durante 5 s)
                    final long esperaTime = 5000L; //se espera 5s
                    btnGet.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            lblMensajes.setBackgroundColor(Color.parseColor("#0099CC"));
                            lblMensajes.setTextColor(Color.parseColor("#FFFFFF"));

                            btnGet.setEnabled(true);
                            lblMensajes.setText("Pulsa el botón");

                            //ivNo.setVisibility(View.INVISIBLE);
                            ivOk.setVisibility(View.INVISIBLE);
                            //ivAlerta.setVisibility(View.INVISIBLE);
                        }
                    }, esperaTime);

                }           


            }
        });




    }


    public String hazYManda(int ipu) {
        //Esta función construye una cadena y con ella hace un GET a mi servidor.

        //Este es un ejemplo simplificado. Con la cadena recibida vía GET, el servidor
        //hace unas cuantas consultas a una base de datos MySQL y según el resultado de esas consultas
        //devuelve una cadena que es "<0>" si va todo bien o, en caso contrario, <1> o <2> según la incidencia

        //construyo la cadena ABCD:1
        String scadena = "ABCD:";
        scadena += Integer.toString(ipu);

        //construyo la cadena para hacer GET
        String xurl = "http://miservidor/fichero.php?key=" + scadena;

        String sj = hacerGet(xurl); //aquí sj recibiría la respuesta del servidor
        //que puede ser null si no responde, <0> si va todo bien o <1> si hay fallo.
        //Es importante esperarse a la respuesta del servidor

        return sj;

    }




    public String hacerGet(String url) {
        //final TextView lblMensajes = (TextView) findViewById(R.id.lblMensajes);

        // Instantiate the RequestQueue.

        scode = null;

        RequestQueue queue = Volley.newRequestQueue(this);


        // Request a string response from the provided URL.
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        if (response == "") scode = "Sin respuesta";
                        else scode = response;
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                //scode = "Error";
                //errServidor = error.getMessage();
                scode = error.getMessage();
            }

        });


        stringRequest.setRetryPolicy(new DefaultRetryPolicy(5000, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        queue.add(stringRequest);



        return scode;
    }





}

I hope to be as clear as possible. Anyway, let's see if we can do it.

Thank you very much.

    
answered by 22.11.2017 в 16:36