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<android-developers%2bunsubscr...@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<android-developers%2bunsubscr...@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<android-developers%2bunsubscr...@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<android-developers%2bunsubscr...@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

Reply via email to