问题发生在
Element element = it.next();
包含该行的代码位于 OnTouchEvent
OnTouchEvent
for (Iterator<Element> it = mElements.iterator(); it.hasNext();){ Element element = it.next(); if(touchX > element.mX && touchX < element.mX + element.mBitmap.getWidth() && touchY > element.mY && touchY < element.mY + element.mBitmap.getHeight()) { //irrelevant stuff.. if(element.cFlag){ mElements.add(new Element("crack",getResources(), (int)touchX,(int)touchY)); element.cFlag = false; } } }
所有这一切都在里面synchronized(mElements),这里mElements是一个ArrayList<Element>
synchronized(mElements)
mElements
ArrayList<Element>
当我触摸时Element,它可能会激活cFlag,这将创建另一个Element具有不同属性的属性,这些属性会从屏幕上掉下来并在不到一秒钟的时间内销毁自己。这是我创建粒子效果的方式。我们可以将其称为“粒子” crack,就像构造函数中的String参数一样。
Element
cFlag
crack
String
一切正常,直到我添加另一个main为止Element。现在,我同时Elements在屏幕上有两个,如果我触摸最新的Element,它可以正常工作并启动粒子。
Elements
但是,如果我触摸并激活cFlag了较旧的,则为我Element提供了例外。
07-28 15:36:59.815: ERROR/AndroidRuntime(4026): FATAL EXCEPTION: main 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): java.util.ConcurrentModificationException 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at com.Juggle2.Panel.onTouchEvent(Panel.java:823) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at android.view.View.dispatchTouchEvent(View.java:3766) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1767) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1119) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at android.app.Activity.dispatchTouchEvent(Activity.java:2086) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1751) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at android.view.ViewRoot.handleMessage(ViewRoot.java:1785) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at android.os.Handler.dispatchMessage(Handler.java:99) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at android.os.Looper.loop(Looper.java:123) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at android.app.ActivityThread.main(ActivityThread.java:4627) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at java.lang.reflect.Method.invokeNative(Native Method) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at java.lang.reflect.Method.invoke(Method.java:521) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:893) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:651) 07-28 15:36:59.815: ERROR/AndroidRuntime(4026): at dalvik.system.NativeStart.main(Native Method)
我该如何工作?
当你使用遍历列表时(通过添加或删除元素)修改列表时,会发生ConcurrentModificationExceptionIterator。
ConcurrentModificationExceptionIterator
尝试
List<Element> thingsToBeAdd = new ArrayList<Element>(); for(Iterator<Element> it = mElements.iterator(); it.hasNext();) { Element element = it.next(); if(...) { //irrelevant stuff.. if(element.cFlag){ // mElements.add(new Element("crack",getResources(), (int)touchX,(int)touchY)); thingsToBeAdd.add(new Element("crack",getResources(), (int)touchX,(int)touchY)); element.cFlag = false; } } } mElements.addAll(thingsToBeAdd );
同样,你应该按照Jon的建议考虑对每个循环进行增强。