Evan R.
Evan R.

Reputation: 1244

Is it Possible to get results of AsyncTask as an Arraylist Hashmap

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

Answers (3)

Evan R.
Evan R.

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

Lalit Poptani
Lalit Poptani

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

Venkatesh S
Venkatesh S

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

Related Questions