我有一个适配器,它在我的活动中扩展了BaseAdapter。在适配器中我列出了记录。当用户单击任何记录时,将列出选项。这些选项是“发送”和“删除”。删除选项从列表中删除记录并将选项发送记录发送到服务器。按下发送时,将启动asynctask。对于删除操作,我在对话框中使用处理程序。(是或否)。
我的问题是,如果我在其他记录发送时在一条记录中按删除,应用程序崩溃了,我得到了这个例外;
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
at java.util.ArrayList.get(ArrayList.java:304)
E/AndroidRuntime(25140): atandroid.widget.HeaderViewListAdapter.isEnabled(HeaderViewListAdapter.java:164)
我多次检查尺寸,尺寸不是0.我确信尺寸不是问题。
此代码来自我的删除操作;
public class MyAdapter extends BaseAdapter{
CopyOnWriteArratList<MyObject> MyCopyonWriteArrayList;
private Handler handler;
private ListView listview;
public MyAdapter(Context context,
CopyOnWriteArratList<MyObject> MyCopyonWriteArrayList,ListView listView){
this.context = context;
this.MyCopyonWriteArrayList= MyCopyonWriteArrayList;
this.listView = listView;
}
new Thread(new Runnable() {
@Override
public void run() {
//If I remove this line, app does not crash
MyObject o = MyCopyonWriteArrayList.get(position);
o.Delete();
MyCopyonWriteArrayList.remove(position);
//Code arrive here.
}
handler.post(new Runnable() {
//Code cannot arrive here
@Override
public void run() {
progressDialog.dismiss();
deleteDoneListener.deleteDone();
}
});
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
我的asyntask非常典型。
我的问题是为什么我得到这个例外“索引0,大小0”?这个大小不是myarraylist大小。
如何修复此代码以及此大小的来源是什么?
另外如果我在删除中使用asynctask而不是handler,我得到“无法在未调用Looper.prepare()的线程内创建处理程序”的异常。所以我不能把asyntack放在对话框里。
答案 0 :(得分:2)
只需检查位置是否在范围内,如果是,请将其删除并进行如下更改:
if(position != -1 && position < MyCopyonWriteArrayList.size()) {
MyCopyonWriteArrayList.remove(position);
}
肯定会帮助你
答案 1 :(得分:0)
我在做什么,怎么做,以及我得到的几乎和你的一样!这可能会有所帮助:
在使用ListView的自定义适配器时,我遇到了同样的异常。并且从Android标准库类抛出了异常,甚至没有导致我的任何代码行。 我还添加了Header,因此我的适配器被HeaderViewListAdapter隐式包装。 在我的情况下,当我从适配器删除数据时会出现问题。
我认为问题是因为ListView或适配器无法正常使用Header,但实际上原因是其他原因。
我的解决方案是确保永远不会从其他线程更改适配器的数据,并从UI线程调用notifyDataSetChanged()
。
因此,修复后一切正常,我的代码如下:
// Loader's callbacks
@Override
public Loader<...> onCreateLoader(int id, Bundle args) {
return new Loader...
}
@Override
public void onLoadFinished(Loader<...> loader, Data data) {
...
// adapter's list of items
listItems.clear();
listItems.addAll(data);
adapter.notifyDataSetChanged();
...
}
@Override
public void onLoaderReset(Loader<List<? extends Map<String, ?>>> loader) {
...
}
// custom loader
private static class ContactAsyncLoader extends AsyncTaskLoader<...> {
@Override
public List<..> loadInBackground() {
Data data = new ..
...
return data;
}
}