Return data obtained from OnResponse

3

How do I return this String reponse? If I give the return there it does not accept ... and if and by at the end of the method and using an auxiliary variable it risks returning 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;
}
    
asked by anonymous 20.10.2016 / 01:41

1 answer

4

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

You are passing a listener object whose method onResponse will 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 execution and only at some point after onResponse will execute. Therefore, it is impossible to want to return the value below.

There are two ways to resolve this. One of them is forcing the main method to wait for the completion of the request. But this is a bad practice because it will block the whole program. Most Android APIs are asynchronous in nature to avoid blockages and allow you to cancel such operations.

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

Example

I would write an example but found something that exactly answers your question in 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 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 it does what it needs 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 display a loader to inform the user that you are loading the data and also implement another callback to handle errors.     

20.10.2016 / 02:16