What I want to do: run a background thread which calculates ListView contents and update ListView partially, while results are calculated.
What I know I have to avoid: I cannot mess with ListAdapter contents from background thread, so I inherited AsyncTask and publish result (add entries to adapter) from onProgressUpdate. My Adapter uses ArrayList of result objects, all operations on those arraylists are synchronized.
Research of other people: there is very valuable data here. I also suffered from almost daily crashes for group of ~500 users, and when I added list.setVisibility(GONE)/trackList.setVisibility(VISIBLE)
block in onProgressUpdate, crashes lowered by a factor of 10 but not disappeared. (it was suggested in answer )
What I got sometimes: please notice, it happens really rarely (once a week for one of 3.5k users). But I'd like to get rid of this bug completely. Here is partial stacktrace:
`java.lang.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(2131296334, class android.widget.ListView) with Adapter(class com.transportoid.Tracks.TrackListAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1432)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:2062)
at android.widget.ListView.onTouchEvent(ListView.java:3234)
at android.view.View.dispatchTouchEvent(View.java:3709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:852)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
[...]
Help? Not needed anymore, see below
FINAL ANSWER: As it turned out, I was calling notifyDataSetChanged
every 5 insertions to avoid flickering and sudden list changes. It cannot be done such way, always notify adapter when base list changes. This bug it long gone for me now.