【问题标题】:Android Canvas SurfaceView black screenAndroid Canvas SurfaceView 黑屏
【发布时间】:2016-05-18 14:16:30
【问题描述】:

我有以下课程:

public class GameView extends SurfaceView implements SurfaceHolder.Callback {

public static final int WIDTH = 860;
public static final int HEIGHT = 480;

int x = 0;

GameLoop gameLoop;

public GameView(Context context) {
    super(context);
    getHolder().addCallback(this);
    setFocusable(true);
}

public GameView(Context context, AttributeSet attrs) {
    super(context, attrs);
    getHolder().addCallback(this);
    setFocusable(true);
}

public GameView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    getHolder().addCallback(this);
    setFocusable(true);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    //setWillNotDraw(false);

    gameLoop = new GameLoop(this);

    gameLoop.start();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if(canvas != null) {
        Paint paint = new Paint();
        paint.setColor(Color.WHITE);
        canvas.drawRect(x, 0, 200, 200, paint);
        canvas.drawRect(200, 200, 400, 400, paint);
        Log.v("TEST", "Drawing into canvas");
        Log.v("TEST", "x := " + x);
    }
}

public void update() {
    x += 5;
}

还有一个如下所示的游戏循环:

public class GameLoop extends Thread {
public static final int REFRESH_TIME = 2;
private static final int LOG_FPS_AFTER_FRAMES = 30;

public static Canvas canvas;

private double averageFPS;

private GameView gameView;

private boolean running;

public GameLoop(GameView gamePanel) {
    this.gameView = gamePanel;
}

@Override
public void run() {
    super.run();

    running = true;

    long startTime;
    long timeMillis;
    long waitTime;
    long totalTime = 0;
    int frameCount = 0;
    long targetTime = 1000*REFRESH_TIME;

    while(running) {
        startTime = System.nanoTime();
        canvas = null;

        try {
            canvas = gameView.getHolder().lockCanvas();

            synchronized (gameView.getHolder()) {
                gameView.update();
                gameView.draw(canvas);
            }


        } catch(Exception e) {}
        finally {
            if(canvas != null) {
                try {
                    gameView.getHolder().unlockCanvasAndPost(canvas);
                } catch(Exception e) {}
            }
        }


        timeMillis = (System.nanoTime() - startTime) / 1000000;
        waitTime = targetTime - timeMillis;

        try {
            this.sleep(waitTime);
        } catch(Exception e) {}

        totalTime += System.nanoTime() - startTime;
        frameCount++;

        if(frameCount == LOG_FPS_AFTER_FRAMES) {
            averageFPS = 1000/((totalTime/frameCount)/1000000);
            frameCount = 0;
            totalTime = 0;
            Log.v("FPS", Double.toString(averageFPS));
        }

    }

}

@Override
public void interrupt() {
    super.interrupt();

    running = false;
}

public boolean isRunning() {
    return running;
}

public void setRunning(boolean value) {
    this.running = value;
}

}

每两秒调用一次 OnDraw 方法,但屏幕仍然是黑色的。任何想法可能是什么问题? (顺便说一句,如果我取消注释行 setWillNotDraw(false) 矩形被绘制一次但不移动)...

【问题讨论】:

    标签: android canvas surfaceview


    【解决方案1】:

    你有一个常见的问题:你覆盖了onDraw(),它利用了 View 部分。所以你有一个非常昂贵的自定义视图,它不能正常工作。如果您让视图绘制,它会绘制一次,但您不会调用invalidate(),因此它永远不会再次发生。我的猜测是你在布局中设置了背景颜色,使 View 变得不透明,这就是为什么你看不到 Surface 上正在绘制的内容。

    对于 Canvas 渲染,使用custom View 通常比使用 SurfaceView 更好。我会推荐这种方法。

    如果您真的想使用 SurfaceView,请将onDraw() 更改为其他内容(例如doDraw()),然后从您的渲染线程中调用它。由于您将在 Surface 部分而不是 View 部分上绘图,因此您不需要将 SurfaceView 子类化(也不应该,因为使其成为一个独立的类将避免常见的陷阱,例如您陷入的陷阱)。确保您了解SurfaceView and Activity interact 的原因,因为有多种方法会惹上麻烦。

    您还应该阅读构建game loop 的推荐方法。

    【讨论】:

      【解决方案2】:

      我刚刚将重写函数 onDraw(Canvas canvas) 更改为 draw(Canvas canvas) 并且它可以工作!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-01
        • 1970-01-01
        • 2012-06-11
        • 1970-01-01
        相关资源
        最近更新 更多