我偶尔会遇到一个非常奇怪的异常:
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;
}
}
当列表先前已填充然后清空时,该错误抬起了丑陋的头,离开size == 0
并且firstIndex == lastIndex > 0
您尝试添加足够大的集合以使其不适合lastIndex
当前数组大小。
从 2.2 开始,当该addAll
方法被重写并growAtEnd
从类中消失时,该错误就消失了。
谢谢雷库德的指点!