【问题标题】:Error java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0 in Android adapter错误 java.lang.IndexOutOfBoundsException:无效索引 0,Android 适配器中的大小为 0
【发布时间】:2012-12-09 08:27:27
【问题描述】:

我有一个在我的活动中扩展 BaseAdapter 的适配器。在适配器中,我列出了记录。当用户单击任何记录时,将列出选项。这些选项是“发送”和“删除”。删除选项从列表中删除记录并发送选项发送记录到服务器。当发送被按下时,异步任务被启动。对于删除操作,我在对话框中使用处理程序。(是或否)。

我的问题是,如果我在一个记录中按删除,而其他记录正在发送,应用程序崩溃,我得到了这个异常;

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();
            }

我的异步任务很典型。

我的问题是为什么我得到这个异常“索引 0 ,大小 0”?这个大小不是 myarraylist 大小。

我该如何修复这个代码,这个尺寸的来源是什么?

另外,如果我在删除中使用 asynctask 而不是处理程序,我会得到“无法在未调用 Looper.prepare()] 的线程内创建处理程序”异常。所以我不能在对话框中放入 asyntack。

【问题讨论】:

  • 检查你的arraylist MyCopyonWriteArrayList,使用logcat打印arraylist。
  • 我检查了arraylist很多次,大小从不为0。
  • 你想做什么?我认为那段代码还不够。例如,我想知道MyCopyonWriteArrayList 的定义位置以及添加元素的位置。
  • 我编辑了问题并在 MyAdapter 类中定义了它。我将元素传递给 MyAdapter 类。请问您需要哪一部分,我会补充问题。

标签: android android-asynctask android-adapter android-handler


【解决方案1】:

只要检查位置是否在范围内,如果是则删除它并进行如下更改:

if(position != -1 && position < MyCopyonWriteArrayList.size()) {
     MyCopyonWriteArrayList.remove(position); 
 }

肯定会帮到你

【讨论】:

  • 我已经添加了这些行。即使大小> 0,我也有异常。在我的问题中,我已经说过这个异常不是来自 MyCopyonWriteArrayList。代码可以成功删除对象,但是当它到达处理程序时,发生异常。
【解决方案2】:

我在做什么,怎么做,我得到的几乎和你一样!这可能会有所帮助:

在使用带有 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;
    }
}

【讨论】:

    猜你喜欢
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    相关资源
    最近更新 更多