可能导致此异常的原因是什么?

时间:2012-04-18 22:53:21

标签: java android exception arraylist

我偶尔会遇到一个非常奇怪的例外:

  

04-18 18:08:08.121:E / AndroidRuntime(3031):未捕获的处理程序:由于未捕获的异常而导致主线程退出   04-18 18:08:08.141:E / AndroidRuntime(3031):java.lang.ArrayIndexOutOfBoundsException
  04-18 18:08:08.141:E / AndroidRuntime(3031):at java.util.ArrayList.addAll(ArrayList.java:257)
  04-18 18:08:08.141:E / AndroidRuntime(3031):at com.zigzagworld.text.formatter.FormatManager.formatIfNeeded(FormatManager.java:185)
  等

这是在1.6仿真器上发生的。我的代码中调用addAll的行是:

mTasksAbove.addAll(schedule.above);

我唯一可以想象的是对mTasksAbove的某种并发访问。但是,我一直非常小心地确保所有访问都在同一个对象上同步。我想到的唯一另一件事是schedule.aboveaddAll执行期间被修改了,但我相信会生成ConcurrentModificationException(另外,我不认为我的代码会这样做) 。有谁知道我应该寻找的其他任何东西?

修改

根据Raykud的回答,我做了一点挖掘,发现了确切的错误。在Android 1.6源代码中,addAll方法调用了一个内部方法,growAtEnd是错误的。这是源本身:

private void growAtEnd(int required) {
    int size = size();
    if (firstIndex >= required - (array.length - lastIndex)) {
        int newLast = lastIndex - firstIndex;
        if (size > 0) {
            System.arraycopy(array, firstIndex, array, 0, size);
            int start = newLast < firstIndex ? firstIndex : newLast;
            Arrays.fill(array, start, array.length, null);
        }
        firstIndex = 0;
        lastIndex = newLast;
    } else {
        int increment = size / 2;
        if (required > increment) {
            increment = required;
        }
        if (increment < 12) {
            increment = 12;
        }
        E[] newArray = newElementArray(size + increment);
        if (size > 0) {
            System.arraycopy(array, firstIndex, newArray, 0, size);
            /********************************************************\
            * BUG! The next 2 lines of code should be outside the if *
            \********************************************************/
            firstIndex = 0;
            lastIndex = size;
        }
        array = newArray;
    }
}

当该列表先前已填充然后清空时,该bug会变得丑陋,留下size == 0firstIndex == lastIndex > 0,并且您尝试添加一个足够大的集合,使其不适合{{ 1}}和当前数组大小。

当从lastIndex方法重写并且addAll从课程中消失时,该错误从2.2开始消失。

谢谢,Raykud,指点!

1 个答案:

答案 0 :(得分:1)

从1.5开始,arraylist中的方法addAll是错误的,它应该在未来的realease中被修复,但是我不确定它是什么。 要解决此问题,您可以为集合创建Iterator并逐个添加元素。 这是一个小代码来帮助:

Iterator<MyTypeofObjectToAdd> e = myArrayListToCopyFrom.iterator();
    while (e.hasNext()) {
      arrayListToAdd(e.next());
    }

导致IndexOutOfBounds异常,因为您试图从没有任何内容的位置检索项目。