I getting the exception as
“*java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the cont*ent of your adapter is not modified from a background thread, but only from the UI thread.“
My Code has Two threads one is for SAX parsing and another is thread extending asynctask class
which is checking the contents every time ArrayList contents are changed.. And calling adapter.notifyDatasetChange() method in onProgressUpdate()..
But I want the output as the parser progresses the parsing, the respected element should be
added to the listview…. Please help me guyzzz…..
I have the code as…
public class SearchProperty extends Activity
{
boolean isDone;
List<Property> properties = new ArrayList<Property>();
ListView list;
ArrayAdapter<Property> adapter;
InputStream in;
ProgressDialog dialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newlay);
list = (ListView) findViewById(R.id.mylistview);
list.setPadding(0, 20, 0, 20);
dialog = new ProgressDialog(this);
dialog.setCancelable(true);
dialog.setMessage("Please Wait...");
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
adapter = new ArrayAdapter<Property>(this,
android.R.layout.simple_list_item_1, properties);
list.setAdapter(adapter);
list.setOnItemClickListener( new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int pos,
long id) {
Toast.makeText( SearchProperty.this , "Please Wait... Application is under progress..." , Toast.LENGTH_SHORT).show();
}
});
FileParserTask task = new FileParserTask();
Thread thread = new Thread(task);
thread.start();
SetTimeoutTask task11 = new SetTimeoutTask();
task11.execute();
System.out.println("I m done!!");
}
**// This thread is checking arraylist time to time after 50 ms and call on progressUpdate**
private class SetTimeoutTask extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
dialog.show();
};
protected String doInBackground(String... urls)
{
// Log.e("...","in do InBackground.....");
try {
for (;;) {
if (isDone)
break;
publishProgress();
Thread.sleep(50);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
}
@Override
protected void onProgressUpdate(Void... values)
{
//Log.e("...","in onprogressupdate.....");
super.onProgressUpdate(values);
if(list.getAdapter()!=null)
adapter.notifyDataSetChanged();
}
}
**// this thread is doing parsing of xml file in background....**
class FileParserTask implements Runnable {
@Override
public void run() {
try {
in = getAssets().open("property.xml");
PropertyHandler myhandler = new PropertyHandler(properties);
XMLReader xmlReader = SAXParserFactory.newInstance()
.newSAXParser().getXMLReader();
xmlReader.setContentHandler(myhandler);
xmlReader.parse(new InputSource(in));
isDone = true;
System.out.println("Done!!!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// EstateParser.parse(in,properties,adapter);
catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Taking some snippet of the code from above:
Then you have
The way you described your code, looks like you are adding to
propertiesin from theFileParserTask(even though I cant see that in your code above). If i am right and you are adding topropertiesinFileParserTaskthen it could be likely that you ll get this error. Reason being, your underlinepropertiesis modified in a NON-UI Thread which means yourArrayAdapteris also modified in NON-UI thread.This leads to inconsistent state and you get the above exception. Try to move your parser code to
AsyncTaskwith slight design change.One option is load all properties in a separate list and then create and set new adapter on
ListViewinonPostExecute. This will work if you dont want to see updatedListViewwhile the content is being added but you still want to see the progress status.Second option is, create a temp list to store few properties as you parse. When the list is reached a certain limit (say 5) then
publishProgressand inonProgressUpdateyou can add this to the otherListwhich is attached to the adapter. NOTE: You have try this one to see how it behaves.