我在 Android OS v4.x(尤其是 4.0.3)上遇到了一个问题,即在滚动时更改 ListView 的数据 - 发生崩溃说我试图更改不是来自主 UI 线程的数据,这是不正确的:
E/AndroidRuntime(2453): 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(16908298, class android.widget.ListView) with Adapter
(class mypackage.activity.MyListViewActivity$ListViewAdapter)]
带有 ListView 的 UI 由两部分组成——最大的一个是 ListView,底部有一个特殊的控件,可以触发数据更改,并且该控件始终可见。因此,用户能够启动 ListView 滚动,并且在滚动时用户能够使用触发 ListView 数据更改的控件,这会导致崩溃。当然,数据更改发生在 mainUI 线程上,我确实使用了 notifyDataSetChanged():
monthChanger.setOnMonthChangedListener(new OnMonthChangedListener() {
@Override
public void monthDidChange(int month) {
currentMonth = month;
loadData();
listAdapter.notifyDataSetChanged();
}
});
loadData() 方法只是用其他数据填充相应的 ArrayList:
void loadData() {
List<DataHolder> tempDataList = DataRetriever.getData(currentMonth);
dataList.clear();
dataList.addAll(tempDataList);
}
所以这里没有什么特别的。AOS 2.3.5 不会发生崩溃。在 AOS 4 上获得相同崩溃的另一种方法是在数据更改并且 ListView 滚动到顶部后立即点击屏幕。
出了什么问题以及如何避免此错误?