As soon as you change the count you must notifyDatasetChanged(). On Fri, Nov 20, 2009 at 10:59 PM, Robert Woodruff <woodman...@gmail.com> wrote: > Hi Romain, > > > > Thanks for the info. I think you are saying that the small example below, > all of which runs on the UI thread, will cause the exception to be thrown? > Right? > > > >> 1. Change the count in the base adapter > >> 2. notifyDataSetChanged() // Which captures a count and will react some >> time in the future > >> 3. Immediately change the count in the base adapter, again > > > > Even though the count is only ever changed in the UI thread? It may explain > why the exception is being thrown in one of my apps by ListView even though > the adapter count is only ever changed in the UI thread. > > > > Say there is a thread running, in an AsyncTask, gathering data to be placed > in the adapter. It reaches a point to report that data is to be added to the > Adapter. The AsyncTask.doInBackground() calls publishProgress() which > queues a Handler on the UI thread to eventually call onProgressUpdate(). > > > > Eventually the onProgressUpdate() Handler runs on the UI thread and causes > the adapter count to change. But notifyDataSetChanged() was called before > the publishProgress () Handler runs and the Handler runs before the ListView > Handler comes around to update the list. So ListView throws an exception > because it sees a different count than when notifyDataSetChanged() was > called. But the Adapter count was changed always on the UI thread. > > > > This brings back the question: When is it safe to change the count in a > BaseAdapter()? It seems like there should be a semaphore or listener or > something that says "Now it is OK to change the count/Now it is NOT OK to > change the count" Or maybe notifyDataSetChanged() could tell the ListView it > to suspend operations, update the count and continue operations. > > > > If I am not too far off base with this it would be good to know when it is > safe to change the adapter count. > > > > Thank you, > > On Fri, Nov 20, 2009 at 4:14 PM, Romain Guy <romain...@google.com> wrote: >> >> > 1. Change the count in the base adapter >> > 2. notifyDataSetChanged() // Which will react some time in the future >> > 3. immediately change the count in the base adapter, again >> >> > Or another way: when does the ListView grab the BaseAdapter count? Does >> > it >> > grab it on the call to notifyDataSetChanged() or whenever it later >> > starts >> > the update operation? >> >> It grabs it in notifyDatasetChanged(). Also, the count change must >> happen on the UI thread. >> >> > >> > Thank you, >> > >> > On Thu, Nov 19, 2009 at 2:24 PM, Dianne Hackborn <hack...@android.com> >> > wrote: >> >> >> >> As the exception says: >> >> >> >> throw new 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. [in ListView(" + getId() >> >> + >> >> ", " + getClass() >> >> + ") with Adapter(" + mAdapter.getClass() + >> >> ")]"); >> >> >> >> You can't modify an adapter from a background thread; this must be done >> >> on >> >> the main thread. >> >> >> >> This exception is not adding a restriction; it is making it more >> >> obvious >> >> when you do something that would always break in weird, subtle, and/or >> >> horrible ways. >> >> >> >> On Thu, Nov 19, 2009 at 5:56 AM, WoodManEXP <woodman...@gmail.com> >> >> wrote: >> >>> >> >>> For Google about BaseAdapter class >> >>> >> >>> In Android 1.6 and 2.0 the BaseAdapter class has apparently been >> >>> modified to throw an exception when it sees the Adapter.getCount() >> >>> method return a number different than what it picked up when >> >>> BaseAdapter.notifyDataSetChanged() was called (at least I did not >> >>> observe this behavior in pre 1.6). >> >>> >> >>> So now the question is, when should one call notifyDataSetChanged() or >> >>> more importantly, when can the count in the Adapter be safely changed? >> >>> >> >>> Consider the case of an app with a background thread delivering data >> >>> to a BaseAdapter at a rate faster than the ListView responds to >> >>> notifyDataSetChanged(). Because notifyDataSetChanged() is a >> >>> synchronous call and the ListView updates are taking place sometime in >> >>> the indeterminate future on the UI thread, how can an app know when it >> >>> is safe to change the adapter count? >> >>> >> >>> If the app changes the count while the ListView is updating itself the >> >>> exception will be thrown (and there is no way to catch the exception). >> >>> >> >>> Is there a way to know when it is safe to change the count in the >> >>> BaseAdapter? >> >>> >> >>> -- >> >>> You received this message because you are subscribed to the Google >> >>> Groups "Android Developers" group. >> >>> To post to this group, send email to >> >>> android-developers@googlegroups.com >> >>> To unsubscribe from this group, send email to >> >>> android-developers+unsubscr...@googlegroups.com >> >>> For more options, visit this group at >> >>> http://groups.google.com/group/android-developers?hl=en >> >> >> >> >> >> >> >> -- >> >> Dianne Hackborn >> >> Android framework engineer >> >> hack...@android.com >> >> >> >> Note: please don't send private questions to me, as I don't have time >> >> to >> >> provide private support, and so won't reply to such e-mails. All such >> >> questions should be posted on public forums, where I and others can see >> >> and >> >> answer them. >> >> >> >> -- >> >> You received this message because you are subscribed to the Google >> >> Groups "Android Developers" group. >> >> To post to this group, send email to >> >> android-developers@googlegroups.com >> >> To unsubscribe from this group, send email to >> >> android-developers+unsubscr...@googlegroups.com >> >> For more options, visit this group at >> >> http://groups.google.com/group/android-developers?hl=en >> > >> > -- >> > You received this message because you are subscribed to the Google >> > Groups "Android Developers" group. >> > To post to this group, send email to android-developers@googlegroups.com >> > To unsubscribe from this group, send email to >> > android-developers+unsubscr...@googlegroups.com >> > For more options, visit this group at >> > http://groups.google.com/group/android-developers?hl=en >> >> >> >> -- >> Romain Guy >> Android framework engineer >> romain...@android.com >> >> Note: please don't send private questions to me, as I don't have time >> to provide private support. All such questions should be posted on >> public forums, where I and others can see and answer them >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Android Developers" group. >> To post to this group, send email to android-developers@googlegroups.com >> To unsubscribe from this group, send email to >> android-developers+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/android-developers?hl=en > > -- > You received this message because you are subscribed to the Google > Groups "Android Developers" group. > To post to this group, send email to android-developers@googlegroups.com > To unsubscribe from this group, send email to > android-developers+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/android-developers?hl=en
-- Romain Guy Android framework engineer romain...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en