Android如何正确通知ListView更改的数据集

时间:2012-07-11 00:07:49

标签: android listview

我正在尝试更新我的列表并在我的活动中显示更新的列表。每次我这样做,我都会收到以下错误

 The content of the adapter has changed but ListView did not receive a notification.
 Make sure the content of your adapter is not modified from a background thread,
 but only from the UI thread.

这是我的代码,我正在使用AsyncTask来完成这项任务。我在我的适配器上调用notifyDataSetChanged()但它似乎不起作用。我做错了什么?

  class MyTask extends AsyncTask<Context, Integer, String> {

    @Override
    protected String doInBackground(Context... params) {
        GregorianCalendar currentDateclone = (GregorianCalendar) currentDate.clone();
        ListPopulater2.listPopulate(currentDateclone, 7, items, Id);
                    //method to update list info




    }

    // -- gets called just before thread begins
    @Override
    protected void onPreExecute() {
        progressdialog = ProgressDialog.show(SectionListExampleActivity.this, "", "Loading..."); //display progress bar
        super.onPreExecute();

    }

    // -- called as soon as doInBackground method completes
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.d("postExecute", "here");
                    adapter.notifyDataSetChanged();

        progressdialog.cancel();
    }
}

2 个答案:

答案 0 :(得分:3)

尝试移动:

ListPopulater2.listPopulate(currentDateclone, 7, items, Id);

onPostExecute

这样做的原因是因为您需要在完成所有后台活动后更新列表,而不是在您执行此操作时。您可以使用onProgressUpdate,但这适用于您的进度对话框。在拥有所有数据后,应该更新列表视图,否则,您将收到错误,因为UI在主线程上运行,并且您尝试使用后台线程更新它。

至于进度对话框,有一个目的。如果您正在做一些需要一段时间才能完成的事情,该对话框将告诉用户您完成后台任务的距离。

希望这是有道理的。

答案 1 :(得分:2)

当你想要做一些处理UI的事情时,你必须在UI线程中完成这项任务。 因此,您可以使用2种方法:

  1. 使用runOnUi()方法
  2. 使用OnPostExecute()方法
  3. 你必须在listView中设置适配器的地方使用notifyDatasetchanged()。