2

非常に奇妙な例外が発生することがあります。

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 == 0firstIndex == lastIndex > 0lastIndex

addAllメソッドが書き直さgrowAtEndれてクラスから消えた2.2で、バグはなくなりました。

Raykud、ポインタをありがとう!

4

1 に答える 1

1

1.5の時点で、arraylistのメソッドaddAllにはバグがあり、将来のリリースで修正される予定でしたが、どちらかはわかりません。これを回避するには、コレクションのイテレータを作成し、要素を1つずつ追加します。役立つ小さなコードを次に示します。

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

また、何もない位置からアイテムを取得しようとしているため、IndexOutOfBounds例外が発生します。

于 2012-04-18T23:17:42.083 に答える