I’m trying to call .notifyDataSetChange() on a SimpleCursorAdapter displayed in a ListView from an XML-parsing non-UI thread and can’t for the life of me figure out how. I’ve searched all over and all I’ve found are articles that talk about refreshing from within the ListView itself, which I’m not doing. I can’t figure out a way to pass in the adapter or get it from the parent or whatever I need to do to call a method on it from another thread.
The ListView will update fine the next time I launch the activity, but I want it to refresh as soon as the XML parsing is done so that the user will see the new data immediately.
The answer’s probably simple; it’s just eluding me. Thanks in advance for any help!
Here’s my code:
public class DirectoryListActivity extends DirectoryActivity {
public final Handler mHandler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.directory_list);
// Populate the ListView
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(
directoryPeople.PEOPLE_TABLE
);
String asColumnsToReturn[] = {
//snip
};
mCursor = queryBuilder.query(mDB, asColumnsToReturn, null, null,
null, null, directoryPeople.DEFAULT_SORT_ORDER);
startManagingCursor(mCursor);
// HERE'S THE ADAPTER
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.directory_people_item, mCursor,
new String[]{
//snip
new int[]{
//snip
);
ListView av = (ListView)findViewById(R.id.listPeople);
av.setAdapter(adapter);
//Perform sync in background
startXMLParseThread();
}
public void startXMLParseThread() {
new Thread () {
boolean success = false;
public void run() {
try {
// XML-Parsing and Table-Updating code
} catch (Exception e) {
success = false;
}
mHandler.post(new Runnable() {
public void run() {
TextView txtUpdateStatus = (TextView)findViewById(R.id.txtUpdateStatus);
if (success) {
txtUpdateStatus.setText(R.string.synced);
} else {
txtUpdateStatus.setText(R.string.sync_failed);
}
adapter.notifyDataSetChanged(); // ECLIPSE HATES
}
});
}
}.start();
}
}
}
No need to create a new adapter…
.notifyDataSetChanged()should be called only in case the data rows actually changed (inserted or deleted rows), in case you just updated the values on rows a simple call to requery() on your cursor should be enough:Edit: by your comment I see that you have in fact a compilation problem…
You must declare the adapter as a class member (before/after mHandler declare it:
private SimpleCursorAdapter adapter)Then when you initialize it, replace
with: