Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从ArrayList中绘制路径';行不通_Android - Fatal编程技术网

Android 从ArrayList中绘制路径';行不通

Android 从ArrayList中绘制路径';行不通,android,Android,当我在屏幕上移动手指时,尝试绘制路径时,我的应用程序强制关闭。代码开始在路径中绘制一些线,但随后强制关闭。我做错了什么 MainActivity类中的OnTouchListener: @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: gameLoop.touchD

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

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)

这就是drawObjects中的所有代码吗?LogCat告诉我们您在迭代列表时正在修改列表。我希望您有这样一个代码,它会中断:

    for(Point point: points) {
        path.lineTo(point.x, point.y);
        canvas.drawPath(path, paint);
        points.remove(point); // this line added
    }
编辑:

哦,您可能正在使用
SurfaceView
并在单独的线程中绘制。在这种情况下,您需要将调用同步到点列表。可能使用
CopyOnWriteArrayList

请阅读关于穿线的文章

Edit2:

类似的东西应该可以工作,但我真的不会在生产代码中使用它,因为它会阻塞线程。为了使线程高效地工作,您需要非常少量的代码(就执行时间而言)。(添加了4行,注释为
添加了该行

这是:

// 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

您在哪里调用
drawObjects
?异常表示您正在同时修改来自多个线程的点集合。您需要同步对集合的访问,以便在另一个线程迭代其内容时,不能从一个线程进行任何修改。您可能需要试一试。我正在canvas=surfaceHolder.lockCanvas()之间通过run()方法调用drawObjects;和surfaceHolder.unlockCanvasAndPost(画布);我猜列表必须在我触摸手指并存储点的同时进行修改,同时迭代列表才能画出线!?有更好的方法吗?是的,我正在使用SurfaceView,但我应该同步什么?@3D Krativ如果你不做复杂的计算(而且看起来不像你做的那样)来绘制东西,我建议现在扩展
视图
onDraw
,而不是让事情复杂化。同步将不会有问题。但是如果你想坚持使用
SurfaceView
-只需使用
synchronize(…){}
block.Hmm包装所有对点的访问变量,这很难理解!我应该在上面的代码前面使用synchronize(..):if(startDrawLine){….?感谢添加的代码!现在它可以工作了,但它会大大降低画布上其他移动对象的速度!这可能是什么原因?我认为SurfaceView比View更好使用,为什么不将其用于生产?很难知道什么是好的,什么是坏的!我应该如何改进我的代码?
// 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