当我在屏幕上移动手指时,当我试图绘制路径时,我的应用程序强制关闭。代码开始绘制路径中的一些行,但随后强制关闭。我做错了什么?
MainActivity类中的OnTouchListener:
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
gameLoop.touchDownX = event.getX();
gameLoop.touchDownY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
Point point = new Point();
point.x = (int) event.getX();
point.y = (int) event.getY();
gameLoop.addPoints(point);
gameLoop.startDrawLine = true;
break;
case MotionEvent.ACTION_UP:
gameLoop.touchUpX = event.getX();
gameLoop.touchUpY = event.getY();
gameLoop.touchActionUp = true;
break;
}
return true;
}
GameLoop类中的draw方法:
// Method to draw objects
private void drawObjects(Canvas canvas) {
// Clear screen with black color
canvas.drawRGB(0, 0, 0);
// Draw line
if(startDrawLine) {
// Set properties to Paint object
paint.setColor(Color.WHITE);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
// Draw path
path.moveTo(touchDownX, touchDownY);
for(Point point: points) {
path.lineTo(point.x, point.y);
canvas.drawPath(path, paint);
}
path.reset();
}
LogCat信息:
04-28 11:54:23.155: W/dalvikvm(2896): threadid=10: thread exiting with uncaught exception (group=0x40018578)
04-28 11:54:23.155: E/AndroidRuntime(2896): FATAL EXCEPTION: Thread-11
04-28 11:54:23.155: E/AndroidRuntime(2896): java.util.ConcurrentModificationException
04-28 11:54:23.155: E/AndroidRuntime(2896): at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576)
04-28 11:54:23.155: E/AndroidRuntime(2896): at com.androidTest.mergemania.GameLoop.drawObjects(GameLoop.java:251)
04-28 11:54:23.155: E/AndroidRuntime(2896): at com.androidTest.mergemania.GameLoop.run(GameLoop.java:216)
04-28 11:54:23.155: E/AndroidRuntime(2896): at java.lang.Thread.run(Thread.java:1019)
答案 0 :(得分:1)
是drawObjects中的所有代码吗? LogCat告诉我们您在迭代时修改列表。我希望你有这样的代码打破:
for(Point point: points) {
path.lineTo(point.x, point.y);
canvas.drawPath(path, paint);
points.remove(point); // this line added
}
修改强>
哦,你可能正在使用SurfaceView
并在一个单独的线程中绘图。在这种情况下,您需要将调用与点列表同步。也许使用CopyOnWriteArrayList
。
请阅读SurfaceView上的线索。
<强> EDIT2:强>
这样的东西应该可行,但我真的不会在生产代码中使用它,因为它会阻塞线程。您需要拥有非常少量的代码(就执行时间而言)才能使线程高效工作。 (添加了4行,注释了this line added
)。
@Override
public boolean onTouch(View v, MotionEvent event) {
synchronized (gameLoop) { // this line added
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
gameLoop.touchDownX = event.getX();
gameLoop.touchDownY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
Point point = new Point();
point.x = (int) event.getX();
point.y = (int) event.getY();
gameLoop.addPoints(point);
gameLoop.startDrawLine = true;
break;
case MotionEvent.ACTION_UP:
gameLoop.touchUpX = event.getX();
gameLoop.touchUpY = event.getY();
gameLoop.touchActionUp = true;
break;
}
} // this line added
return true;
}
和此:
// Method to draw objects
private void drawObjects(Canvas canvas) {
synchronized (this) { // this line added
// Clear screen with black color
canvas.drawRGB(0, 0, 0);
// Draw line
if(startDrawLine) {
// Set properties to Paint object
paint.setColor(Color.WHITE);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
// Draw path
path.moveTo(touchDownX, touchDownY);
for(Point point: points) {
path.lineTo(point.x, point.y);
canvas.drawPath(path, paint);
}
path.reset();
}
} // this line added