0

当我在屏幕上移动手指时尝试绘制路径时,我的应用程序强制关闭。代码开始在路径中绘制一些线,但随后它强制关闭。我做错了什么?

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

日志信息:

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)
4

1 回答 1

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上的线程。

编辑2:

这样的东西应该可以工作,但我真的不会在生产代码中使用它,因为它会阻塞线程。您需要有非常少量的代码(就执行时间而言)才能使线程有效地工作。(添加了 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
于 2013-04-28T10:08:18.800 回答