I\'ve written a ListActivity that has a custom list adapter. The list is being updated from a ContentProvider when onCreate is run. I also have a service that gets started
You have to do all your updating of Adapter data on the UI thread so the synchronized block isn't necessary. It's also useless since your synchronizing on the AsyncTask
which is created new each time it's executed.
Another problem is that you are calling notifyDataSetChanged
external to the Adapter
. You should call it at the end of your setListItems
method. That shouldn't be causing errors though since it's being executed on the UI thread but it should not be called in that way.
You should make sure that your getReports
method is not modifying the backing store of the Adapter
in any way. Since it is running on a separate thread it cannot modify anything the Adapter
has access too. Even if it's protected by locks. What you need to do is in your doInBackground
method is generate the list of updates or a new list, etc., and pass that into onPostExecute
which then commits the new data to the Adapter
on the UI thread. So, if your getReports
function is changing report_list
and your Adapter
has a reference to report_list
you are doing it wrong. getReports
must create a new report_list
and then pass that back to your Adapter
when it's finished creating it on the UI thread.
To reiterate, you can only modify data the Adapter
and subsequently the ListView
has access too on the UI thread. Using synchronization/locks does not change this requirement.
If you want to update the UI listview from a service then you should call notifyDataSetChanged() on onDestroy of the service
make the adapter static from your main activity and call that adaptername.notifyDataSetChanged()
like this
@Override
public void onDestroy() {
if (MainActivity.isInFront == true) {
if (MainActivity.adapter != null)
MainActivity.adapter.notifyDataSetChanged();
MainActivity.listView.setAdapter(MainActivity.adapter);
}
}