我在后台创建ListView的内容,当添加每个项目时,我更新ListView适配器。通常它工作正常,但有时我得到这个错误。奇怪的是,它在我的Galaxy s4 mini中比在我的HTC Sensation中发生的次数多10倍。我不明白为什么会发生这种情况,因为我通过UI线程清楚地通知适配器。有什么想法吗?
java.lang.IllegalStateException: 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. Make sure your adapter calls
notifyDataSetChanged() when its content changes. [in ListView(2131100779, class
util.TouchInterceptor) with Adapter(class com.bill.deuterh.ListActivity$ListAdapter)]
的AsyncTask:
private class AsyncCaller extends AsyncTask<Void,Void,Void>{
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
ListActivity.this.runOnUiThread(new Runnable(){
@Override
public void run() {
findViewById(R.id.progress_bar).setVisibility(View.GONE);
}
});
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
for (int i=0;i<table.length;i++){
if(isCancelled()){break;}
myList.add(createObject(table[i])));
ListActivity.this.runOnUiThread(new Runnable(){
@Override
public void run() {
ListAdapter.notifyDataSetChanged();
}
});
}
return null;
}
}
(如果重要的话,我将Listview转换为TouchInterceptor,这是一个修改过的google类,用于支持通过拖放重新排列listview项目。)
答案 0 :(得分:0)
这应该只在onpostexecute结束时运行一次而不需要runonuithread。 ListAdapter.notifyDataSetChanged();
删除它:
ListActivity.this.runOnUiThread(new Runnable(){
@Override
public void run() {
ListAdapter.notifyDataSetChanged();
}
});
并把它:
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
findViewById(R.id.progress_bar).setVisibility(View.GONE);
ListAdapter.notifyDataSetChanged();
}
答案 1 :(得分:0)
不要在doInBackground(Void... params)
中编写与UI相关或更新的任何代码。对于UI上的更新,使用Async的onPostExecute(Void result)
方法。
因此,请从doInbackGround(Void... params){}
答案 2 :(得分:0)
试试这个:如果其他一切都设置正确。然后,此代码将在列表视图中立即显示您doInBackground
的所有更新=良好的用户体验!
private class AsyncCaller extends AsyncTask<Void,Void,Void>{
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
findViewById(R.id.progress_bar).setVisibility(View.GONE);
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
for (int i=0;i<table.length;i++){
if(isCancelled()){break;}
myList.add(createObject(table[i])));
publishProgress();
}
return null;
}
protected void onProgressUpdate(Void.. values) {
ListAdapter.notifyDataSetChanged();
}
}
OnPreExecute, onPostExecute and onProgressUpdate
已在UIThread上运行。也许你没有以正确的方式执行asynctask。这就是为什么没有数据更新的原因?