2012-07-11 59 views
2

我正在尝试更新我的列表并在我的活动中显示更新的列表。每次我这样做,我得到以下错误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(); 
    } 
} 
+1

与你的问题没有关系,但你为什么在'onPostExecute(...)'中使用'runOnUiThread(...)'?无论如何,'AsyncTask'的所有方法(除了'doInBackground(...)')都在UI线程上运行。 – Squonk 2012-07-11 00:46:41

+0

我刚刚尝试的东西,没有它的工作原理。我只是删除它清晰 – 2012-07-11 00:49:45

回答

3

尝试移动:

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

onPostExecute

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

至于进度对话框,有一个目的。如果你正在做的事情需要一段时间才能完成,对话框会告诉用户你有多接近完成后台任务。

希望是有道理的。

+0

这工作,但任何解释为什么这将是?这种杀死进度对象的目的 – 2012-07-11 00:17:38

+0

我理解你在说什么,但是如果我将填充方法移动到onPostExecute,那么在doInBackground方法中没有任何操作。我对AsyncTask的理解是加载可以在后台完成,然后一旦完成onPostExecute被调用。 – 2012-07-11 01:01:09

+0

我认为在方法listPopulate你试图更新一些数据模型没有得到反映onPostExecute可能是因为doInBackground在后台线程中运行? – anargund 2012-07-11 01:04:28

2

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

  1. 使用runOnUi()方法
  2. 使用OnPostExecute()方法

而且你在哪里设置你在那个地方使用notifyDatasetchanged()适配器在listView中。