非常に奇妙な例外が発生することがあります。
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
addAll
メソッドが書き直さgrowAtEnd
れてクラスから消えた2.2で、バグはなくなりました。
Raykud、ポインタをありがとう!