Jayesh Salvi <jayeshsalvi <at> gmail.com> writes:

> 
> 
> Hi,This is regarding the exception:  "java.lang.IllegalStateException: The
content of the adapter has 
> changed but ListView did not receive a notification....." - seen on Android
1.6+This problem has been discussed in the past [1][2][3][4], and I have
followed all the solutions suggested in those threads. However, few of my users
still hit this crash. So I did some source code lookup and have some
questions.Here is the description of what my app is doing:I use a ListView and
populate it with an adapter. The adapter is a direct derivative of BaseAdapter.
I populate the list progressively. As the items are downloaded from network they
get added to the adapter. The fetching of items is done in doInBackground() and
when they are ready to get added to the adapter I invoke publishProgress(), in
the onProgressUpdate() method I add new items one-by-one to the adapter. As soon
as I add the item to the adapter, I invoke notifyDataSetChanged().I believe this
is as per the best practices that Android developers have suggested in above
mentioned threads.Despite this I get crash reports with this exception. They are
rare, but not as rare as ignorable. I myself have hit this crash on my
phone/emulator only 1-2 times in last couple of months. The user reported
crashes are roughly 1 to 3 per day (approx. at least 600 users use the app per
day) (A minority of users may be hitting this crash over and over again)
> 
> . This leads me to believe that my adapter update logic is mostly right, but
not full proof. So I dug into the source code of ListView and BaseAdapter.The
exception is thrown because ListView's mItemCount doesn't match the underlying
adapter's item count. It happens in layoutChildren() [ListView.java line 1432]
> 
> ....             } else if (mItemCount != mAdapter.getCount()) {             
  throw new IllegalStateException("The content of the adapter has changed but " 
                      + "ListView did not receive a notification. Make sure the
content of "
> 
> ....So in order to avoid this from happening mItemCount should be updated as
soon as the adapter has changed its content. So I searched for locations in the
code where mItemCount is updated. I found two locations doing that. In
setAdapter() [ListView.java 431] and in onMeasure() [ListView.java 1033].
Consequently, if I am updating the adapter then either setAdapter() or
onMeasure() should be executed before the comparision in layoutChildren() takes
place, otherwise the exception will be thrown.My question is, is it possible
that my code in onProgressUpdate() that appends to adapter can get executed
between onMeasure() and layoutChildren() of the ListView? AFAIU, all three of
these methods (onProgressUpdate, onMeasure, layoutChildren) run on the same GUI
thread.I call notifyDataSetChanged immediately after I add to adapter in
onProgressUpdate(). I looked into its source code. It calls methods on
DataSetObservable and DataSetObserver. I couldn't find how it could directly
lead to the updating of mItemCount of the ListView, clearly I don't know much of
the internal layout code.Please let me know what you think. I am trying to
understand this mechanism as thoroughly as possible. Thanks in advance.Links:[1]
http://www.mail-archive.com/android-developers <at> 
googlegroups.com/msg60355.html
> 
> [2] http://www.mail-archive.com/android-developers <at>
googlegroups.com/msg65814.html[3]
http://groups.google.com/group/android-developers/browse_thread/thread/77722caa85f87697
> 
> [4]
http://groups.google.com/group/android-developers/browse_thread/thread/a451221261cb6a93/2ab5bea015c38437?lnk=gst&q=For+Google+about+BaseAdapter+class#2ab5bea015c38437
> 
> [5] ListView.java source code I refered to:
http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/java/android/widget/ListView.java;h=7c8151e65132a91aecadd2048fe205bd1c6768a9;hb=HEAD--Jayesh
> 
>

Hello Jayesh. 

Were you able to resolve the issue you were having? I am getting the same
IllegalStateException, but it seems like this happens only when scrolling.

Thanks,
- Doug




-- 
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