【问题标题】:Is it Possible to get results of AsyncTask as an Arraylist Hashmap是否可以将 AsyncTask 的结果作为 Arraylist Hashmap 获取
【发布时间】:2012-09-17 05:07:39
【问题描述】:

我的应用程序中现在至少有三个活动,它们使用 AsyncTask 将 JSON 结果返回到 ListView。我已经开始开发这个应用程序,但是一旦他掌握了基础知识,另一个人就会接管开发,所以我想尝试让事情尽可能易于使用。这意味着我正在尝试将尽可能多的可重复代码转换为可调用函数,因此每次需要查询 Web 服务时不需要复制/粘贴/重用 30-40 行代码,他们只需将参数传递给一个函数。

目前,我在一项通过 php 网络服务从 mysql 数据库中提取体育课程列表的活动中具有以下内容:

    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

    }

}

我想把它移到我拥有的另一个类,称为“WebServiceTasks”,这样我就可以在活动的 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);

虽然我已经尝试过这个,但我得到了一些与定义 asyncTask 错误或其他不匹配的错误有关的错误。

这是我尝试放入“WebServiceTasks”类的内容:

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

    }

}

这可能吗,如果可以,我做错了什么?

【问题讨论】:

  • 看这个例子Seperate AsyncTwsk
  • 感谢您的链接。我尝试按照您的代码进行操作,虽然我认为它可能有效,但我现在在“doinBackground”中的以下行中得到一个空指针异常: final HashMap map = new HashMap();跨度>
  • 无视,我忘了初始化arraylist。结合使用您的代码和 Lalit 的代码,我能够让它工作,将我的结果作为答案发布。谢谢你们俩。

标签: android arraylist android-asynctask


【解决方案1】:

好吧,您正在尝试使用 AsyncTask 的 get() 方法,该方法非常昂贵,因为它会阻塞 UI,直到您的 onPostExecute() 完成。我会坚持让您在onPostExecute() 中触发BroadCastReceiver 以更新您的UI 或创建Interface 并使用onPostExecute() 中的该接口将结果传递给您的活动。我刚刚创建了一个小演示,用于使用 BroadCastReceiver 和 Interface 将结果从 onPostExecute() 传递到您的 Activity。你可以在我的githubhere找到一个demo源码。

【讨论】:

  • Lalit,我接受你的回答,因为 Samir 没有提供答案,只是一个提交,但你的两个例子都帮助我弄清楚了。再次感谢您!
【解决方案2】:

您可以创建一个 Bean 类来存储来自异步任务的所有值,以便您可以将其接收到我的朋友的另一个类

【讨论】:

  • 感谢回复,我得研究一下beans看看怎么用。
【解决方案3】:

对于任何试图复制此问题的人,以下是我使用 Lalit 和 Samir 的示例解决此问题的方法:

在我的活动中:

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");

}

在名为“AsyncTaskCompleteListener”的接口中:

public interface AsyncTaskCompleteListener {
    void onTaskComplete(ArrayList<HashMap<String, String>> allclasseslist);
}

还有单独的 WebServiceTasks 类:

    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);
    }

}

感谢大家的快速帮助。这最终在使用此代码的每个活动中节省了 120 多行重复代码。

【讨论】:

  • 但在我的活动中,我也实现了 onclickListener。所以异步任务的构造函数总是获取 onclick 监听器参数而不是自定义接口监听器。
猜你喜欢
  • 1970-01-01
  • 2019-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多