ListView错误 - java.lang.IllegalStateException

时间:2014-02-10 20:16:24

标签: android listview custom-adapter notifydatasetchanged

我的ListView出现了这个错误:

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. Make sure your adapter calls notifyDataSetChanged() when its content changes

在我的应用程序中,我有一个带有CustomAdapter的ListView。

在OnCreate方法中我有:

list = new ArrayList<FriendVO>();
mListView = (ListView) this.findViewById(R.id.listView1);
    mFriendAdapter =  new FriendAdapter(null);
    mListView.setAdapter(mFriendAdapter);

我还有一个AsyncHttpResponseHandler,它从我的webservice获取数据以填充我的ListView。 Everthing可以正常工作。在AsyncHttpResponseHandler的onFinish()方法中,我正在更新List View的数据。

当我到达onFinish()方法时,我已经有了数据列表。

@Override
        public void onFinish(){

                    mFriendAdapter.setData(list);
                    mListView.setOnItemClickListener(itemClickListener);
        }

这是我的自定义适配器:

private class FriendAdapter extends BaseAdapter {

    private List<FriendVO> mData;
    private LayoutInflater mInflater;

    public FriendAdapter(List<FriendVO> data) {
        mData = data;
        mInflater = FaceVsFaceActivity.this.getLayoutInflater();
    }

    public void setData(List<FriendVO> data) {
        mData = data;
        this.notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        if (mData != null)
            return mData.size();
        else
            return 0;
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO: If id is needed, change it
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        RowViewsHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.friend_row, parent, false);
            holder = new RowViewsHolder(convertView);
            convertView.setTag(holder); // Save inside view the holder.
        } else {
            holder = (RowViewsHolder) convertView.getTag();
        }

        FriendVO vo = mData.get(position);
        holder.eventName.setText(vo.getName());

        holder.eventImage.setImageResource(R.drawable.image);

        return convertView; 
    }   
}

private class RowViewsHolder {
    private ImageView eventImage;
    private TextView eventName;

    public RowViewsHolder(View rowView) {
        eventImage = (ImageView) rowView.findViewById(R.id.img_friend);
        eventName = (TextView) rowView.findViewById(R.id.friend_name);

        }
}

可以为此提供什么解决方案?我想我在使用列表时会出现错误(滚动,单击)并且数据正在更新。请一点帮助。

2 个答案:

答案 0 :(得分:0)

您正在从不是UI线程的线程修改适配器,Android不喜欢它。你可以使用 调用mFriendAdapter.setData(list)的Activity.runOnUiThread()方法;打电话并避免这种例外。你需要将它包装在Runnable中。

答案 1 :(得分:0)

来自AsyncHttpResponseHandler文档的

“所有处理都应该用这四种方法之一处理,然后调用在UI线程上运行一个新的runnable,或者在UI线程上运行的onFinish中处理”

因此,在onFinish中设置适配器不是问题。

我不喜欢将事物设置为null然后如果你不需要更改它们,那么我对你的onCreate进行了更改。另外,我建议调用notifyDataSetChanged而不是setData。试一试,让我知道会发生什么。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contact_picker_main);

        list = new ArrayList<FriendVO>();
        mListView = (ListView) this.findViewById(R.id.listView1);

        mFriendAdapter =  new FriendAdapter(list);
        mListView.setAdapter(mFriendAdapter);

    }

@Override
    public void onFinish(){

        mFriendAdapter.notifyDataSetChanged();
        mListView.setOnItemClickListener(itemClickListener);
    }

另外,改变这个:

@Override
    public int getCount() {
        if (mData != null)
            return mData.size();
        else
            return 0;
    }

到此:

@Override
    public int getCount() {
        return mData.size();
    }

你的mData永远不应为null(在最坏的情况下,它将为空,因此大小为零)如果是,则需要修复一个问题。这种空检查只会导致您不想要注意的问题。

最后。您的适配器设置为允许任何对象作为mData传递。将您的getItem从Object更改为FriendVO,以便更好地控制和保持一致性。