1

java.util.ConcurrentModificationException在我的应用程序中得到了一个,但前提是我快速连续执行多个触摸事件,并且似乎对较慢的设备(三星 Galaxy S)而不是较快的设备(Galaxy S3)有更大的影响。

我有一个队列,其中存储了一个 int 数组,用于存储相应线的点的不透明度和数据。当不透明度达到 0 时,我从队列中删除该行,因此不再绘制它。

这是堆栈跟踪:

01-10 14:06:27.847: E/AndroidRuntime(2081): java.util.ConcurrentModificationException
01-10 14:06:27.847: E/AndroidRuntime(2081):     at java.util.LinkedList$LinkIterator.next(LinkedList.java:124)
01-10 14:06:27.847: E/AndroidRuntime(2081):     at com.android.mcameron.singletrack.Options$TestSurfaceView.drawLinesInvalid(Options.java:559)
01-10 14:06:27.847: E/AndroidRuntime(2081):     at com.android.mcameron.singletrack.Options$TestSurfaceView.run(Options.java:438)
01-10 14:06:27.847: E/AndroidRuntime(2081):     at java.lang.Thread.run(Thread.java:1019)

这些是遍历队列的 2 个函数,我执行删除操作。

    private void drawLinesInvalid() {
        paint.setColor(Color.RED);

        for (Iterator<int[]> iterator = invalidLines.iterator(); iterator.hasNext();) {
            int[] invalidLine = iterator.next(); // Line 559 with the error
            float[] line = {invalidLine[1], invalidLine[2], invalidLine[3], invalidLine[4]};

            Xfermode originalXfermode = paint.getXfermode();
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            mCanvas.drawLines(line, paint);
            paint.setXfermode(originalXfermode);
            paint.setAlpha(invalidLine[0]);
            mCanvas.drawLines(line, paint);
        }
    }

    private void decreaseLineOpacity() {
        for (Iterator<int[]> iterator = invalidLines.iterator(); iterator.hasNext();) {
            int[] line = iterator.next();
            if (line[0] <= 0) {
                iterator.remove();
            }
        }

        for (Iterator<int[]> iterator = invalidLines.iterator(); iterator.hasNext();) {
            int[] line = iterator.next();
            line[0] -= 10;
        }
    }

我在这里查看了一些其他问题,大多数人似乎在使用 Foreach 循环以及remove()在队列而不是迭代器上执行操作时遇到问题。我认为这两者都不适用于这里。也像上面说的那样,我可以摆脱触摸,所以这不是立即发生的错误。在抛出异常之前,我有时可以触摸 30-50 次。

4

2 回答 2

1

感谢 Peter Lawrey,我使用了CopyOnWriteArrayList

我将队列更改为:

private CopyOnWriteArrayList<int[]> invalidLines = new CopyOnWriteArrayList<int[]>();

然后将我的 reductionLineOpacity 更新为:

private void decreaseLineOpacity() {
    int position = 0;
    for (Iterator<int[]> iterator = invalidLines.iterator(); iterator.hasNext();) {
        int[] line = iterator.next();
        if (line[0] <= 0) {
            invalidLines.remove(position);
        }
        position++;
    }

    for (Iterator<int[]> iterator = invalidLines.iterator(); iterator.hasNext();) {
        int[] line = iterator.next();
        line[0] -= 10;
        Log.d("Counting", "Opacity: "+ line[0]);
    }
}

我已经点击了几分钟,它没有抛出异常,所以看起来不错

于 2013-01-10T13:53:15.533 回答
0

ListIteratorandroid中使用的LinkedList支持修改。因此,正如@Peter Lawrey 所建议的那样,您的问题必须与多线程有关。尝试同步这两种方法。如果这会影响性能,您可以尝试CopyOnWriteArrayList,但这并不能保证您在线程中迭代时看到最新的更改,因为您正在迭代列表的副本。

于 2013-01-10T13:55:02.227 回答