码迷,mamicode.com
首页 > 编程语言 > 详细

java.lang.IllegalStateException

时间:2015-05-29 12:20:05      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!