2013-01-10 40 views
1

我在我的應用程序中獲得java.util.ConcurrentModificationException,但只有在快速成功執行多個觸摸事件時,並且似乎對較慢設備(Samsung Galaxy S)有更多影響反對更快的(Galaxy S3)。java.util.ConcurrentModificationException僅在多個觸摸事件之後

我有一個隊列,我存儲一個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 imes。

+1

根據你的代碼,看起來'decreaseLineOpacity'和'drawLinesInvalid'被同時調用。我會嘗試像CopyOnWriteArrayList這樣的線程安全列表。 –

+0

好吧,我一個接一個地給他們打電話,很有可能。 –

回答

1

感謝Peter Lawrey,我用了一個CopyOnWriteArrayList

我改變了我的隊列,以這樣的:

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

,然後更新了我的decreaseLineOpacity這樣:

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]); 
    } 
} 

我一直點擊了幾分鐘,並沒有拋出異常,所以看起來不錯

+0

不錯的工作@Mark :) –

0

ListIterator在Android中使用支持修改的LinkedList。因此,您的問題必須與@Peter Lawrey建議的多線程相關。試試同步兩種方法。如果這會影響性能,您可以嘗試CopyOnWriteArrayList,但這並不能保證您在線程中迭代時看到最新更改,因爲您正在迭代列表副本。