I’m trying to put content from a JSON feed I have into an ListView, handling HTTP requests using the Android Asynchronous Http Client. However, I think the nature of the requests causes the adapter to receive a null value rather than the Array of data I want it to.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ApplicationGlobal g = (ApplicationGlobal) getApplication();
boolean userLoggedIn = g.getUserLoggedIn();
AsyncHttpClient clientSession = new AsyncHttpClient();
PersistentCookieStore cookieStore = g.getCookieStore();
clientSession.setCookieStore(cookieStore);
if (!userLoggedIn) {
login();
} else {
ArrayList<HashMap<String, String>> newsFeed = getNewsJson();
// Second to be printed:
System.out.println("LIST DATA");
System.out.println(newsFeed);
SimpleAdapter adapter = new SimpleAdapter(
this,
newsFeed,
R.layout.assignment_list_row_view,
new String[] { "photo", "dateAssigned", "dateDue",
"description" },
new int[] { R.id.text1, R.id.text2, R.id.text3, R.id.text4 });
setListAdapter(adapter);
}
}
ArrayList<HashMap<String, String>> newsFeed = new ArrayList<HashMap<String, String>>();
private ArrayList<HashMap<String, String>> getNewsJson() {
ApplicationGlobal g = (ApplicationGlobal) getApplication();
AsyncHttpClient clientSession = new AsyncHttpClient();
PersistentCookieStore cookieStore = g.getCookieStore();
clientSession.setCookieStore(cookieStore);
clientSession.get("http://192.168.1.42:5000/news/dummy/all/",
new JsonHttpResponseHandler() {
@Override
public void onSuccess(JSONObject response) {
JSONArray assignments = new JSONArray();
try {
assignments = response.getJSONArray("assignments");
JSONObject c = assignments.getJSONObject(0);
for (int i = 0; i < assignments.length() + 1; i++) {
JSONObject individualAssignment = new JSONObject(
c.getString(Integer.toString(i)));
HashMap<String, String> map = new HashMap<String, String>();
map.put("photo",
individualAssignment.getString("photo"));
map.put("dateAssigned", individualAssignment
.getString("date_assigned"));
map.put("dateDue", individualAssignment
.getString("date_due"));
map.put("description", individualAssignment
.getString("description"));
newsFeed.add(map);
// Last to be printed (and printed multiple times, as expected)
System.out.println("RAW DATA");
System.out.println(newsFeed);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
// First to be printed:
System.out.println("RETURNED DATA");
System.out.println(newsFeed);
return newsFeed;
}
I think what is happening, as shown in the three placed comments above, is that onSuccess() is not called soon enough for the data to be passed on into the adapter with a non-null value.
What would be the best way to go about redesigning this code snippet to work properly?
The method will return the newsFeed instantly whilst the Async stuff is still executing.
Putting the initialization of the adapter in the onSuccess flow will probably fix your problem.
I would recommend using AsyncTask for background operation since it’s much more clearer what is being performed in the background and knowing what should be processed by the main (UI) thread.
AsyncTask info: http://developer.android.com/reference/android/os/AsyncTask.html