Return data obtained in Onresponse

Asked

Viewed 731 times

3

How do I make the return of this String rest? If I give the Return there it does not accept... and if and at the end of the method and use an auxiliary variable runs the risk of returning a null.

public String getData(){
    StringRequest request = new StringRequest(
            Request.Method.POST,
            Config.urlMaster,

            new Response.Listener<String>(){
                @Override
                public void onResponse(String response) {

                    JSONArray array;
                    try {
                        array = new JSONArray(response.toString());
                        String json = array.getJSONObject(0).toString();
                        Log.i("Script", "SUCCESS: "+response);

                        //return response; 
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(contexto, "Error: "+error.getMessage(), Toast.LENGTH_LONG).show();
                }
            }){

    };

    request.setTag("tag");
    requisicao.add(request);

    return null;
}
  • Related http://answall.com/q/150458/2541

1 answer

4


The first step to solving the problem is to understand how code execution works.

You’re passing an object Listener whose method onResponse shall be invoked as a callback when the request is completed. The execution of such a method is not linear but asynchronous in nature.

This means that the main method will finish the execution and only sometime after the onResponse will execute. Therefore, it is impossible to return the value below.

There are two ways to solve this. One is by forcing the main method to wait for the completion of the request. But this is bad practice, because it will block the whole program. Most Android Apis are asynchronous in nature precisely to prevent blockages and allow cancelling such operations.

Therefore, my advice would be that you change your strategy. Instead of returning the data, you should pass to the method a method callback which will receive the data and be executed when the request completes.

Example

I was going to write an example, but I found something that exactly answers your question on Soen. I’ll just adapt the code.

First you create an interface to serve callback:

public interface VolleyCallback {
    void onSuccess(String response);
}

Then change your method to receive the callback:

public void getData(final VolleyCallback callback) {
    StringRequest request = new StringRequest(
            Request.Method.POST,
            Config.urlMaster,

            new Response.Listener<String>(){
                @Override
                public void onResponse(String response) {

                    JSONArray array;
                    try {
                        array = new JSONArray(response.toString());
                        String json = array.getJSONObject(0).toString();
                        Log.i("Script", "SUCCESS: "+response);

                        //passa o valor para o método callback
                        callback.onSuccess(response); 
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(contexto, "Error: "+error.getMessage(), Toast.LENGTH_LONG).show();
                }
            }){

    };

    request.setTag("tag");
    requisicao.add(request);

    return null;
}

Finally, you call the method by passing the callback where you do what you need to do with the data:

getData(new VolleyCallback() {
     @Override
     public void onSuccess(String response) {
         //executa a ação aqui com o response obtido
     }
});

Optionally, you can show a Loader to inform the user that is loading the data and also implement another callback to handle errors.

  • 1

    Thank you so much! It worked like a glove for me... I only modified a few things so that it would return me an object sent by parameter, so I increased the reusability of my method that can be used to fetch any data from my database and turn it into any model of my application, provided the parameters are passed correctly. I am not on PC, but later I will post the solution developed

Browser other questions tagged

You are not signed in. Login or sign up in order to post.