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

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)
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 に答える