android-LV数据源初始化异常

解决java.lang.IllegalStateException: The content of the adapter has changed but ListView…的问题
分类: Android 2014-03-06 09:47 10104人阅读 评论(4) 收藏 举报
androidadapterUI thread
我写了一个Dialog,Dialog中有一个ListView,想要点ListView中的一项后,跳转到另外一个Activity去。

但在使用时,会偶尔报出下面的错误:

02-21 14:54:28.928: E/AndroidRuntime(2846): FATAL EXCEPTION: main

02-21 14:54:28.928: E/AndroidRuntime(2846): 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(2131165196, class android.widget.ListView) with Adapter(class com.jovision.multiscreen.views.DeviceScanSelectDialog DeviceAdapter)]022114:54:28.928:E/AndroidRuntime(2846):atandroid.widget.ListView.layoutChildren(ListView.java:1510)022114:54:28.928:E/AndroidRuntime(2846):atandroid.widget.AbsListView.onTouchModeChanged(AbsListView.java:2077)022114:54:28.928:E/AndroidRuntime(2846):atandroid.view.ViewTreeObserver.dispatchOnTouchModeChanged(ViewTreeObserver.java:591)022114:54:28.928:E/AndroidRuntime(2846):atandroid.view.ViewRoot.ensureTouchModeLocally(ViewRoot.java:2095)022114:54:28.928:E/AndroidRuntime(2846):atandroid.view.ViewRoot.performTraversals(ViewRoot.java:809)022114:54:28.928:E/AndroidRuntime(2846):atandroid.view.ViewRoot.handleMessage(ViewRoot.java:1861)022114:54:28.928:E/AndroidRuntime(2846):atandroid.os.Handler.dispatchMessage(Handler.java:99)022114:54:28.928:E/AndroidRuntime(2846):atandroid.os.Looper.loop(Looper.java:130)022114:54:28.928:E/AndroidRuntime(2846):atandroid.app.ActivityThread.main(ActivityThread.java:3683)022114:54:28.928:E/AndroidRuntime(2846):atjava.lang.reflect.Method.invokeNative(NativeMethod)022114:54:28.928:E/AndroidRuntime(2846):atjava.lang.reflect.Method.invoke(Method.java:507)022114:54:28.928:E/AndroidRuntime(2846):atcom.android.internal.os.ZygoteInit MethodAndArgsCaller.run(ZygoteInit.java:895)
02-21 14:54:28.928: E/AndroidRuntime(2846): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653)
02-21 14:54:28.928: E/AndroidRuntime(2846): at dalvik.system.NativeStart.main(Native Method)

其中错误描述:

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.

的意思大体是,你的adapter的内容变化了,但是你的ListView并不知情。请保证你adapter的数据在主线程中进行更改!

知道了原因,改起来就好办多了,我将我的adapter类改为:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
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();  
}  

以下略)
相对于原来,我做了两项改动:

1.将所有数据“完全”保存在adapter内部,即使有外部数据进入,也会用.clone()重新生成副本,保证了数据完全是由adapter维护的。

2.保证所有setDeviceList()/clearDeviceList()是从主线程里调用的,如何保证是从主线程中调用的呢:

  a.调用Activity.runOnUIThread()方法;

  b.使用Handler(其实这并不非常准确,因为Handler也可以运行在非UI线程);

  c.使用AsyncTask。

希望能帮到遇到同样问题的同学~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值