我偶尔会遇到一个非常奇怪的例外:
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.above
在addAll
执行期间被修改了,但我相信会生成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 == 0
和firstIndex == lastIndex > 0
,并且您尝试添加一个足够大的集合,使其不适合{{ 1}}和当前数组大小。
当从lastIndex
方法重写并且addAll
从课程中消失时,该错误从2.2开始消失。
谢谢,Raykud,指点!
答案 0 :(得分:1)
从1.5开始,arraylist中的方法addAll是错误的,它应该在未来的realease中被修复,但是我不确定它是什么。 要解决此问题,您可以为集合创建Iterator并逐个添加元素。 这是一个小代码来帮助:
Iterator<MyTypeofObjectToAdd> e = myArrayListToCopyFrom.iterator();
while (e.hasNext()) {
arrayListToAdd(e.next());
}
导致IndexOutOfBounds异常,因为您试图从没有任何内容的位置检索项目。