Android, ListView IllegalStateException: “The content of the adapter has changed but ListView did not receive a notification”

后端 未结 25 2149
执念已碎
执念已碎 2020-11-22 16:59

What I want to do: run a background thread which calculates ListView contents and update ListView partially, while results are calculated.

W

25条回答
  •  花落未央
    2020-11-22 17:38

    Several days ago I met the same problem and causes several thousands of crash per day, about 0.1% of users meet this situation. I tried setVisibility(GONE/VISIBLE) and requestLayout(), but crash count only decreases a little.

    And I finally solved it. Nothing with setVisibility(GONE/VISIBLE). Nothing with requestLayout().

    Finally I found the reason is I used a Handler to call notifyDataSetChanged() after update data, which may lead to a sort of:

    1. Updates data to a model object(I call it a DataSource)
    2. User touches listview(which may call checkForTap()/onTouchEvent() and finally calls layoutChildren() )
    3. Adapter gets data from model object and call notifyDataSetChanged() and update views

    And I made another mistake that in getCount(), getItem() and getView(), I directly use fields in DataSource, rather than copy them to the adapter. So finally it crashes when:

    1. Adapter updates data which last response gives
    2. When next response back, DataSource updates data, which causes item count change
    3. User touches listview, which may be a tap or a move or flip
    4. getCount() and getView() is called, and listview finds data is not consistent, and throws exceptions like java.lang.IllegalStateException: The content of the adapter has changed but.... Another common exception is an IndexOutOfBoundException if you use header/footer in ListView.

    So solution is easy, I just copy data to adapter from my DataSource when my Handler triggers adapter to get data and calls notifyDataSetChanged(). The crash now never happens again.

提交回复
热议问题