好吧,所以我一直在試圖編輯數組中的特定對象時得到併發修改異常。根據我的理解,當您嘗試在同時遍歷數組的同時編輯數組時,會發生這種情況。我嘗試使用迭代器並同步訪問數組的所有內容,但沒有運氣。經過一番研究後,我發現有些人只是將值傳遞給另一個數組,以便編輯第一個數組(我知道它很混亂)。所以我只是說我的代碼現在看起來像仍然有併發修改錯誤
public static void checkECount(int id) {
canUpdate = false;
enemiesList.remove(id);
enemyCount = enemyCount - 1;
ArrayList<Integer> arCount = new ArrayList<Integer>();
int index = 0;
for(Sprite s : enemiesList) {
arCount.add(index);
index++;
}
for(Integer i : arCount){
Sprite ss = enemiesList.get(i);
ss.setID(i);
}
arCount.clear();
canUpdate = true;
}
問題是我仍然得到相同的錯誤!但是,一旦我註釋掉enemiesList.remove(id);行它工作正常(以及它不做我想要的,但它不會再拋出錯誤)。有誰知道這裏發生了什麼?我將在底部添加其餘的代碼和logcat以防萬一需要它們。如果可以的話,請幫助,這個錯誤正在變成我瘋狂存在的禍根。
package com.gametest;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
public class GameSurfaceView extends Activity implements OnTouchListener {
double ran;
int touchX, touchY, screenWidth, screenHeight, objX, objY;
static boolean canUpdate;
static int enemyCount;
static MyView v;
static Bitmap orb, explosion;
static List<Sprite> enemiesList = new ArrayList<Sprite>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
v = new MyView(this);
v.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent me) {
touchX = (int) me.getX();
touchY = (int) me.getY();
for (Sprite sprite : enemiesList) {
sprite.checkTouch(touchX, touchY);
}
return true;
}
});
canUpdate = true;
ran = 0;
orb = BitmapFactory.decodeResource(getResources(), R.drawable.blue_orb);
explosion = BitmapFactory.decodeResource(getResources(), R.drawable.explosion);
createEnemies();
setContentView(v);
}
private void createEnemies() {
if (enemyCount < 5) {
screenWidth = v.getWidth();
screenHeight = v.getHeight();
int listLength = enemiesList.size();
enemiesList.add(new Sprite(v, orb, explosion, screenWidth, screenHeight, listLength));
enemyCount = enemyCount + 1;
}
}
public static void checkECount(int id) {
canUpdate = false;
enemiesList.remove(id);
enemyCount = enemyCount - 1;
ArrayList<Integer> arCount = new ArrayList<Integer>();
int index = 0;
for(Sprite s : enemiesList) {
arCount.add(index);
index++;
}
for(Integer i : arCount){
Sprite ss = enemiesList.get(i);
ss.setID(i);
}
arCount.clear();
canUpdate = true;
}
@Override
protected void onPause() {
super.onPause();
v.pause();
}
@Override
protected void onResume() {
super.onResume();
v.resume();
}
public class MyView extends SurfaceView implements Runnable {
Thread t = null;
SurfaceHolder holder;
boolean isItOk = false;
public MyView(Context context) {
super(context);
holder = getHolder();
}
@Override
public void run() {
while (isItOk == true) {
if (!holder.getSurface().isValid()) {
continue;
}
Canvas c = holder.lockCanvas();
if(canUpdate){
canvas_draw(c);
}
holder.unlockCanvasAndPost(c);
}
}
protected void canvas_draw(Canvas canvas) {
canvas.drawARGB(255, 50, 10, 10);
String ranString = Integer.toString(screenHeight);
ran = Math.random() * 5;
if (ran > 3) {
createEnemies();
}
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(15);
canvas.drawText(ranString, 10, screenHeight - 25, paint);
for (Sprite sprite : enemiesList) {
sprite.sprite_draw(canvas);
}
}
public void pause() {
isItOk = false;
while (true) {
try {
t.join();
} catch (InterruptedException e) {
}
break;
}
t = null;
}
public void resume() {
isItOk = true;
t = new Thread(this);
t.start();
}
}
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
return false;
}
}
而且繼承人的logcat的
01-29 21:58:51.140: E/AndroidRuntime(1135): FATAL EXCEPTION: main
01-29 21:58:51.140: E/AndroidRuntime(1135): java.util.ConcurrentModificationException
01-29 21:58:51.140: E/AndroidRuntime(1135): at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
01-29 21:58:51.140: E/AndroidRuntime(1135): at com.gametest.GameSurfaceView$1.onTouch(GameSurfaceView.java:41)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.View.dispatchTouchEvent(View.java:7122)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1877)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1877)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1877)
01-29 21:58:51.140: E/AndroidRuntime(1135): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1925)
01-29 21:58:51.140: E/AndroidRuntime(1135): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1379)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.app.Activity.dispatchTouchEvent(Activity.java:2396)
01-29 21:58:51.140: E/AndroidRuntime(1135): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1873)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.View.dispatchPointerEvent(View.java:7307)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3172)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3117)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4153)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4132)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4224)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.os.MessageQueue.nativePollOnce(Native Method)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.os.MessageQueue.next(MessageQueue.java:125)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.os.Looper.loop(Looper.java:124)
01-29 21:58:51.140: E/AndroidRuntime(1135): at android.app.ActivityThread.main(ActivityThread.java:4745)
01-29 21:58:51.140: E/AndroidRuntime(1135): at java.lang.reflect.Method.invokeNative(Native Method)
01-29 21:58:51.140: E/AndroidRuntime(1135): at java.lang.reflect.Method.invoke(Method.java:511)
01-29 21:58:51.140: E/AndroidRuntime(1135): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-29 21:58:51.140: E/AndroidRuntime(1135): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-29 21:58:51.140: E/AndroidRuntime(1135): at dalvik.system.NativeStart.main(Native Method)
你使用多個線程?如果是這樣的文檔說_it通常不允許一個線程修改一個集合,而另一個線程迭代它_ – csmckelvey
除非我打開一些我不知道的線程。但我很確定它只是一個。 –
我看到Runnables和't = new Thread(this); t.start();'這意味着你正在使用多個線程。這是除了首先運行你的應用程序的那個。 – csmckelvey