Search code examples
androidjsonasynchronousloopjasynchttpclient

AsyncHttpClient LoopJ and preserving data from onSuccess method


I have this method called "invokeWS". All I want to is to do is to update an ArrayAdapter adapter2 I use in my app with the listdata ArrayList that gets data from a JSON file. I tried different things.

  • The onSuccess is void, so I cannot return anything to the main program. I am good to go inside the try, JSON is parsed and I can see the strings I want in the console but as soon as I get out of the onSuccess, I get an empty Arraylist. So when returning the listdata is empty.
  • Had to also declare the listdata "final", otherwise errors of "accessed from inner class" would appear wherever listdata is on OnSuccess
  • Also Tried to make the ArrayAdapter adapter2 to be updated inside onSuccess but didn't work because it is said it is out of scope.
  • I was going to implement onFinish method, but it even got called before JSON was parsed for a strange reason.

    public static ArrayList<String> invokeWS() {
    AsyncHttpClient client = new AsyncHttpClient();
    final  ArrayList<String>  listdata = new ArrayList<String>();
    client.get("http://xxx.xxx.xxx.xxx:8085/CompanyJersWS/company/showcompany", new  JsonHttpResponseHandler() {  //address to be specified each time, using external IP address
    
    
                @Override
                public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                    System.out.println("Inside Success invokeWS");
                    try {
                        JSONArray json = response.getJSONArray("Companies");
                        System.out.println("JSON is parsed!" +json.toString() + "Length is " + json.length());
                        System.out.println("First value is " + json.getString(0));
                        int i;
                        for (i=0;i<json.length();i++)
                            listdata.add(json.getString(i));
                        System.out.println("Listdata contains" +listdata);
    
    
                    } catch (Exception e) {
                        System.out.println("FAILED invokeWS");
                        e.printStackTrace();
                    }
                }
            }
    
    
    
    );
    
    System.out.println("Listdata out of scope contains" +listdata);
    
    return listdata;
    
    }
    

    This is how I am trying to call invokeWS() from my main class;

    ArrayList<String> tempval = invokeWS();
    

    and this is the adapter2 written in main class, which i want to have listdata from json file as contents.

    ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(this,
            android.R.layout.simple_spinner_item, tempval.toArray(new String[tempval.size()]));
     sp1.setAdapter(adapter2);
    

Thanks for reading!


Solution

  • Something you can do is, after onSuccess pass the "listdata" that you create like a parameter of a function (for example "refreshData"):

        @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                System.out.println("Inside Success invokeWS");
                try {
                    JSONArray json = response.getJSONArray("Companies");
                    System.out.println("JSON is parsed!" +json.toString() + "Length is " + json.length());
                    System.out.println("First value is " + json.getString(0));
                    int i;
                    for (i=0;i<json.length();i++){
                        listdata.add(json.getString(i));
                     }
                 System.out.println("Listdata contains" +listdata);
                 refreshData(listdata);
                 } catch (Exception e) {
                    System.out.println("FAILED invokeWS");
                    e.printStackTrace();
                 }
    
            }
    

    And then use that function to update the array with the new list:

    public void refreshData(ArrayList<String> listdata){
        ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(this,
        android.R.layout.simple_spinner_item, listdata);
       sp1.setAdapter(adapter2);
    
    }