我有一个实现runnable的对象。这个对象是我的游戏视图,处理游戏世界。
Gameview归另一个类所有:游戏。游戏正在处理gameView的UI,所以它在ui-thread上运行。
当用户触摸某些内容时,它会被UI线程捕获。这是因为如果用户触摸技能图标,我需要将关于它的技能的数据传递给gameView。
我的问题是:得到:
java.util.ConcurrentModificationException
at java.util.Vector$Itr.checkForComodification(Vector.java:1193)
at java.util.Vector$Itr.next(Vector.java:1145)
at com.example.benjamin.dungeondweller.RenderSystem.render(RenderSystem.java:55)
at com.example.benjamin.dungeondweller.GameView.run(GameView.java:90)
at java.lang.Thread.run(Thread.java:764)
触摸屏幕时。我怀疑这是因为GameView中的方法仍在UI线程上运行,而不是游戏视图中的线程。
这里要说明的是游戏中的方法(在UI线程上运行): 其中gameView.touch中的第三个参数是技能ID(当前设置为-1)
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
gameView.touch(x,y, -1);
break;
}
return true;
}
gamview.Touch:
public void touch(int screenX, int screenY, int skillId) {
int worldX = renderSystem.screenToWorldX(screenX);
int worldY = renderSystem.screenToWorldY(screenY);
renderSystem.clear();
if (map[worldX][worldY] != 1) {
ArrayList<Point> route = calculateRoute(new Point(0,0), new Point(worldX,worldY));
for (Point p : route) {
renderSystem.addSprite(R.drawable.guy, p.x, p.y);
}
}
(目前只删除屏幕上的每个精灵并添加新的精灵)
发生崩溃时,日志引用gameView中的run方法:
@Override
public void run() {
while (running) {
if (!surfaceHolder.getSurface().isValid()) {
continue;
}
long startTime = System.currentTimeMillis();
int frameSkipped = 0;
//update();
Canvas canvas = surfaceHolder.lockCanvas();
if (canvas != null) {
canvas.drawARGB(255,65,65,65);
renderSystem.render(canvas); <---------- CRASH HERE
surfaceHolder.unlockCanvasAndPost(canvas);
}
long updateTime = System.currentTimeMillis() - startTime;
int sleepTime = (int)(FRAME_PERIOD - updateTime);
if (sleepTime > 0) {
try {
Message msg = new Message();
msg.obj = MAX_FPS;
msg.what = UPDATE_FPS;
handler.dispatchMessage(msg);
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
while (sleepTime < 0 && frameSkipped < MAX_FRAME_SKIPS) {
Message msg = new Message();
msg.obj = 1000 / updateTime;
msg.what = UPDATE_FPS;
handler.dispatchMessage(msg);
// update();
sleepTime+=FRAME_PERIOD;
frameSkipped++;
}
}
}
我认为问题是GameView中的run方法和touch方法在不同的线程上运行但我肯定不能肯定。我如何制作它以便gameView.touch在与gameView.run相同的线程上运行?
编辑:格式代码。
编辑:所以为了进一步澄清,我有一个迭代向量的线程和一个试图删除其中的项目的线程。我如何使它删除向量中的项目的线程运行在与迭代它的线程相同的线程上?