I have a fix for this. Just set the visibility of ur ListView to Gone during
update and back to visible after update. By doing so, u can avoid the
inconsistency of ur adapter and listView item count.

On Mon, Feb 22, 2010 at 3:31 PM, Jayesh Salvi <jayeshsa...@gmail.com> wrote:

> 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<http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/java/android/widget/ListView.java;h=7c8151e65132a91aecadd2048fe205bd1c6768a9;hb=HEAD#l1431>
> ]
> ....
>              } 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<http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/java/android/widget/ListView.java;h=7c8151e65132a91aecadd2048fe205bd1c6768a9;hb=HEAD#l431>]
> and in onMeasure() [ListView.java 
> 1033<http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/java/android/widget/ListView.java;h=7c8151e65132a91aecadd2048fe205bd1c6768a9;hb=HEAD#l1033>].
> 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@googlegroups.com/msg60355.html
> [2]
> http://www.mail-archive.com/android-developers@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
>
>  --
> 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

To unsubscribe, reply using "remove me" as the subject.

Reply via email to