kelunik
kelunik

Reputation: 6908

SurfaceView doesn't get repainted

I am developing a small test game on android. I use a SurfaceView to draw on a Canvas.

Here comes my problem: Only one frame is shown, but listener.draw(..) gets called as it should, so my game is a still image.

A thread calls draw(..) every iteration, but the screen doesn't update.

public class GameView extends SurfaceView implements Runnable, SurfaceHolder.Callback {
    // ...

    @Override
    protected void onDraw(Canvas canvas) {
        if(alive) { // to prevent drawing if view exists but surface isn't created
            // ...

            final int savedState = canvas.save();

            try {
                canvas.clipRect(leftPadding, topPadding, leftPadding + finalWidth, topPadding + finalHeight);
                canvas.translate(leftPadding, topPadding);
                canvas.scale(scaleFactor, scaleFactor);

                if(listener != null)
                    listener.draw(this, canvas);
            } finally {
                canvas.restoreToCount(savedState);
            }
        }
    }

    // ...

    @Override
    public void run() {
        alive = true;

        while(alive) {
            if(!holder.getSurface().isValid())
                continue;

            long currentFrameStart = System.currentTimeMillis();
            deltaFrameTime = currentFrameStart - lastFrameStart;
            lastFrameStart = currentFrameStart;

            listener.update(this, deltaFrameTime);

            Canvas canvas = null;

            try {
                canvas = holder.lockCanvas();

                synchronized(holder) {
                    draw(canvas);
                }
            } finally {
                if(canvas != null) {
                    holder.unlockCanvasAndPost(canvas);
                }
            }

            try {
                Thread.sleep(10);
            } catch(InterruptedException e) {
                // ...
            }
        }
    }

    // ...
}

Upvotes: 2

Views: 1419

Answers (2)

kelunik
kelunik

Reputation: 6908

Googling some more hours gave me a solution:

http://danielnadeau.blogspot.de/2012/01/android-canvas-beginners-tutorial.html

instead of

try {
    canvas = holder.lockCanvas();

    synchronized(holder) {
        draw(canvas);
    }
} finally {
    if(canvas != null) {
        holder.unlockCanvasAndPost(canvas);
    }
}

I now use

try {
    canvas = holder.lockCanvas();

    synchronized(holder) {
        postInvalidate();
    }
} finally {
    if(canvas != null) {
        holder.unlockCanvasAndPost(canvas);
    }
}

Upvotes: 3

Related Questions