标签:
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. ...
ListView遇到频繁更新数据源并显示时报错
adapter里面的数据更新(content)不能在在后台,否则会概率性的报错,报错一般因为更新数据源和notifyDataSetChanged不在一个线程上
一些解决方法:
对线程进行管理,如果当前Actitivty暂停了,及时停止这些线程。
数据更新后,要及时使用notifyDataSetChanged()方法通知UI,避免出现数据不一致的情况。
数据的更新,最好放在主线程中进行。这样可以使用同步数据更新与通知内容更新部分的代码。
在用到多线程的时候,可以对数据做缓存处理, 比如与ListView绑定的数据存储在ArrayList (dataList), 在线程中先将数据加入到临时ArrayList(tmpList) , 最后在调用notifyDataSetChanged()方法通知UI更新之前, 把临时ArrayList(tmpList)中的数据更新到ArrayList(dataList)中, 然后清空临时ArrayList(tmpList)数据。
/* 相对于原来,我做了两项改动: 1.将所有数据“完全”保存在adapter内部,即使有外部数据进入,也会用.clone()重新生成副本,保证了数据完全是由adapter维护的。 2.保证所有setDeviceList()/clearDeviceList()是从主线程里调用的,如何保证是从主线程中调用的呢: a.调用Activity.runOnUIThread()方法; b.使用Handler(其实这并不非常准确,因为Handler也可以运行在非UI线程); c.使用AsyncTask。 */ private class DeviceAdapter extends BaseAdapter { private LayoutInflater inflater; private ArrayList<Device> devices; public DeviceAdapter() { inflater = LayoutInflater.from(mContext); } @SuppressWarnings("unchecked") public void setDeviceList(ArrayList<Device> list) { if (list != null) { devices = (ArrayList<Device>) list.clone(); notifyDataSetChanged(); } } public void clearDeviceList() { if (devices != null) { devices.clear(); } notifyDataSetChanged(); } @Override public int getCount() { return devices == null ? 0 : devices.size(); } //以下略...
java.lang.IllegalStateException
标签:
原文地址:http://my.oschina.net/yaly/blog/422168