I\'m working on a App that should get a JSON response from a webservice and write every element in a listview, I have read that I should work with A
private class LoginAction extends AsyncTaskList<String, Void, ArrayList<SearchResult>> {
@Override
protected ArrayList<SearchResult> doInBackground(String... params) {
List<SearchResults> resultList = new ArrayList<SearchResults>();
Map<String, String> callArgs = new HashMap<String, String>(1);
callArgs.put("suuid", "dtr0bdQGcqwSh3QO7fVwgVfBNWog6mvEbAyljlLX9E642Yfmur");
try {
response = EventPulseCloud.call("ListEvents", callArgs);
} catch (HttpClientException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JsonException e) {
e.printStackTrace();
}
//See here I am running the loop in the background so its not on the main thread, then passing the list off to the onpostexecute that way all the main thread does is set the adapter list and notify it of the data update and the list should be updated on the screen
if( response.get("Type").toString().equals("success")) {
JsonArray records = null;
try {
records = response.getObject ("Data").getArray ("Records");
} catch (JsonException e) {
e.printStackTrace();
}
for(int i = 0; i < records.count(); i++) {
JsonObject record = (JsonObject) records.get(i);
sr1 = new SearchResults();
sr1.setAddress(record.get("address").toString());
resultList.add(sr1);
}
}
return resultList;
}
protected void onPostExecute(ArrayList<SearchResult> resultList) {
setListItems(resultList);
}
}
}
add this line before the oncreate with all your other global var
//here you want to create an adapter var with your base adapter so you can set it the updated list later when you have populated data from the internet
ArrayList<SearchResults> searchResults = new ArrayList<SearchResults>();
MyCustomBaseAdapter adapter = new MyCustomBaseAdapter(this, searchResults)
paste this over your oncreate method (replace it)
//here is just the code to update your main method to reflect all the changes I made
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new LoginAction().execute("");
final ListView lv1 = (ListView) findViewById(R.id.ListView01);
lv1.setAdapter(adapter);
}
and add this method to the adapter(MyCustomnBaseAdapter class) code
public void setListItems(ArrayList<SearchResult> newList) {
searchArrayList = newList;
notifyDataSetChanged();
}
onPostExecute()
happens on the Main UI thread. It looks like you are still doing a fair amount of work in that method that should be done off the UI thread, i.e. processing the response, iterating over JSON objects, etc. Do that in doInBackground()
and have that return a list of results, so the only thing onPostExecute needs to do is pass the new items to your list adapter.
Also, do not use the same ArrayList as the one your adapter holds. If for some reason the adapter discovers that the data has changed without you having called notifyDataSetChanged()
, it will probably crash (or at least display odd behaviors). Create a new ArrayList in your AsyncTask, then put this in your Adapter and call it from onPostExecute:
public void setListItems(ArrayList<SearchResult> newList) {
searchArrayList = newList;
notifyDataSetChanged();
}