Reputation: 1244
I have at least three activities in my app right now that use an AsyncTask to return JSON results into an ListView. I've started work on the app, but another person will take over development as soon as he gets the basics down, so I want to try and make things as easy to use as possible. This means that I'm trying to turn as much repeatable code into callable functions as possible, so instead of needing to copy/paste/reuse 30-40 lines of code each time they need query a webservice, they can just pass in parameters to a function.
Currently, I have the following in an activity that pulls a list of gym classes from a mysql database via a php webservice:
class LoadAllClasses extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
// pDialog = new ProgressDialog(Checkin.this);
// pDialog.setMessage("Loading products. Please wait...");
// pDialog.setIndeterminate(false);
// pDialog.setCancelable(false);
// pDialog.show();
}
/**
* getting All products from url
* */
@Override
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", getclasses_tag));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(SmashGyms.WEBSERVICE_URL,
"POST", params);
// Check your log cat for JSON response
Log.d("CheckinDialog", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// classes found
// Getting Array of Classes
classes2 = json.getJSONArray(TAG_CLASSES);
// looping through All Classes
for (int i = 0; i < classes2.length(); i++) {
JSONObject c = classes2.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_CLASSID);
String name = c.getString(TAG_CLASSNAME);
//String day = c.getString(TAG_DAY);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_CLASSID, id);
map.put(TAG_CLASSNAME, name);
//map.put(TAG_DAY, day);
// adding HashList to ArrayList
allclasseslist.add(map);
Log.d("map: ", map.toString());
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
@Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
runOnUiThread(new Runnable() {
@Override
public void run() {
/**
* Updating parsed JSON data into ListView
* */
adapter = new SimpleAdapter(CheckinDialog.this,
allclasseslist, R.layout.checkin_item,
new String[] { TAG_CLASSID, TAG_CLASSNAME },
new int[] { R.id.pid, R.id.name });
setListAdapter(adapter);
}
});
//pDialog.dismiss();
// updating UI from Background Thread
}
}
I'd like to move this to another class that I have, called "WebServiceTasks", so that I can call something like this in the activity's OnCreate():
allclasseslist = new ArrayList<HashMap<String, String>>();
allclasseslist = new WebServiceTasks.LoadAllClasses().get();
adapter = new SimpleAdapter(CheckinDialog.this,
allclasseslist, R.layout.checkin_item,
new String[] { TAG_CLASSID, TAG_CLASSNAME },
new int[] { R.id.pid, R.id.name });
setListAdapter(adapter);
While I've tried this, I get a number of errors related to either defining the asyncTask wrong, or other things not matching up.
Here is what I've tried putting in my "WebServiceTasks" class:
public static class LoadAllClasses extends
AsyncTask<String, String, ArrayList<HashMap<String, String>>> {
JSONParser jParser = new JSONParser();
ArrayList<HashMap<String, String>> allclasseslist;
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_CLASSES = "classes";
private static final String TAG_CLASSID = "id";
private static final String TAG_CLASSNAME = "class";
private static final String getclasses_tag = "getclasses";
JSONArray classes2 = null;
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
// pDialog = new ProgressDialog(Checkin.this);
// pDialog.setMessage("Loading products. Please wait...");
// pDialog.setIndeterminate(false);
// pDialog.setCancelable(false);
// pDialog.show();
}
/**
* getting All classes from url
* */
@Override
protected ArrayList<HashMap<String, String>> doInBackground(
String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", getclasses_tag));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(SmashGyms.WEBSERVICE_URL,
"POST", params);
// Check your log cat for JSON response
Log.d("CheckinDialog", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// classes found
// Getting Array of Classes
classes2 = json.getJSONArray(TAG_CLASSES);
// looping through All Classes
for (int i = 0; i < classes2.length(); i++) {
JSONObject c = classes2.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_CLASSID);
String name = c.getString(TAG_CLASSNAME);
//String day = c.getString(TAG_DAY);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_CLASSID, id);
map.put(TAG_CLASSNAME, name);
//map.put(TAG_DAY, day);
// adding HashList to ArrayList
allclasseslist.add(map);
Log.d("map: ", map.toString());
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return allclasseslist;
}
/**
* After completing background task Dismiss the progress dialog
* **/
@Override
protected void onPostExecute(
ArrayList<HashMap<String, String>> allclasses) {
// dismiss the dialog after getting all products
//pDialog.dismiss();
// updating UI from Background Thread
}
}
Is this possible, and if so, what am I doing wrong?
Upvotes: 0
Views: 2128
Reputation: 1244
For anyone trying to replicate this, Here is how I solved this, using Lalit and Samir's examples:
In my Activity:
public class CheckinDialog extends ListActivity implements
AsyncTaskCompleteListener {
WebServiceTasks.LoadAllClasses objAsyncTask = new WebServiceTasks.LoadAllClasses(
this);
objAsyncTask.execute();
@Override
public void onTaskComplete(ArrayList<HashMap<String, String>> allclasseslist) {
// TODO Auto-generated method stub
adapter = new SimpleAdapter(CheckinDialog.this, allclasseslist,
R.layout.checkin_item, new String[] { TAG_CLASSID,
TAG_CLASSNAME }, new int[] { R.id.pid, R.id.name });
setListAdapter(adapter);
Log.d("OnTaskComplete", "taskcomplete");
}
In an interface called "AsyncTaskCompleteListener":
public interface AsyncTaskCompleteListener {
void onTaskComplete(ArrayList<HashMap<String, String>> allclasseslist);
}
And the seperate WebServiceTasks Class:
public static class LoadAllClasses extends
AsyncTask<String, String, ArrayList<HashMap<String, String>>> {
JSONParser jParser = new JSONParser();
private final AsyncTaskCompleteListener callback;
private final Activity activity;
public LoadAllClasses(Activity act) {
this.activity = act;
this.callback = (AsyncTaskCompleteListener) act;
}
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_CLASSES = "classes";
private static final String TAG_CLASSID = "id";
private static final String TAG_CLASSNAME = "class";
private static final String getclasses_tag = "getclasses";
JSONArray classes2 = null;
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* getting All classes from url
* */
@Override
protected ArrayList<HashMap<String, String>> doInBackground(
String... args) {
// Building Parameters
ArrayList<HashMap<String, String>> allclasseslist = null;
allclasseslist = new ArrayList<HashMap<String, String>>();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", getclasses_tag));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(SmashGyms.WEBSERVICE_URL,
"POST", params);
// Check your log cat for JSON response
Log.d("CheckinDialog", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// classes found
// Getting Array of Classes
classes2 = json.getJSONArray(TAG_CLASSES);
Log.d("JSONArray", json.getJSONArray(TAG_CLASSES)
.toString());
// looping through All Classes
for (int i = 0; i < classes2.length(); i++) {
JSONObject c = classes2.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_CLASSID);
String name = c.getString(TAG_CLASSNAME);
//String day = c.getString(TAG_DAY);
// creating new HashMap
final HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_CLASSID, id);
map.put(TAG_CLASSNAME, name);
//map.put(TAG_DAY, day);
// adding HashList to ArrayList
allclasseslist.add(map);
//Log.d("map: ", map.toString());
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return allclasseslist;
}
/**
* After completing background task Dismiss the progress dialog
* **/
@Override
protected void onPostExecute(
ArrayList<HashMap<String, String>> allclasseslist) {
super.onPostExecute(allclasseslist);
// dismiss the dialog after getting all classes
callback.onTaskComplete(allclasseslist);
}
}
Thanks to all for the quick help. This ended up saving over 120 lines of repeating code in each activity that used this code.
Upvotes: 0
Reputation: 67286
Well, you are trying to use get()
method of AsyncTask which is very expensive because it blocks the UI until your onPostExecute()
is completed. I would insist you to fire a BroadCastReceiver
in onPostExecute()
to update your UI or create and Interface
and pass the result to your Activity using that interface in your onPostExecute()
. I had just created a small demo for using BroadCastReceiver and Interface for passing result from onPostExecute()
to your Activity. You can find a demo source from my github here
.
Upvotes: 1
Reputation: 5494
You Can Create A Bean class to store all the values from async task so that your can receive it to another class my friend
Upvotes: 0