当锁定的画布不为空时,Android SurfaceView显示空白

时间:2011-08-07 05:47:36

标签: android android-canvas surfaceview

我正在使用视图创建一个简单的游戏,该视图扩展了SurfaceView并使用线程在SurfaceView上绘制图像。游戏将有自己的线程(游戏引擎)来绘制和更新drawables。

我有3个课程来实现这一目标,即BattleActivity,BattleView和BattleThread。 BattleActivity是从另一个活动调用的。 BattleThread将调用BattleView.update()和BattleView.render()来完成这项工作。但我没有看到任何工作。我知道这一切都可以通过日志记录和调试(我试过),但我仍然无法弄清楚哪个是不正确的。有人在乎帮助我吗?


public class BattleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    // Making it full screen
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    //... shortened

    // Create the battle view
    battleView = new BattleView(this);
    battleView.setBackground(battleBackground);
    setContentView(battleView);
}}

BattleView:

public class BattleView  extends SurfaceView implements SurfaceHolder.Callback{
//... shortened

public BattleView(Context context) 
{
    super(context);
    getHolder().addCallback(this);
    // Surface has been created
    battleThread = new BattleThread(getHolder(), this); 
    setFocusable(true);
}

public synchronized void render(Canvas canvas) 
{
    // this function is called when I do debugging, but no image is shown
    // canvas and background is not null
    canvas.drawBitmap(background, 0, 0, null);
}

public synchronized void update()
{
    monsterState = leftMonster.update();
    //... shortened
    rightMonster.update();
}

@Override
public void surfaceCreated(SurfaceHolder holder) 
{
    // Start the thread
    battleThread.setRunning(true);
    battleThread.start();
}}

BattleThread:

public class BattleThread extends Thread {
public BattleThread(SurfaceHolder surfaceHolder, BattleView battleView)
{
    super();
    this.surfaceHolder = surfaceHolder;
    this.battleView = battleView;
}

@Override
public void run() 
{
    Canvas canvas;
    //... shortened

    while (running) 
    {
        canvas = null;
        // try locking the canvas for exclusive pixel editing
        // in the surface
        try 
        {
            canvas = this.surfaceHolder.lockCanvas();
            synchronized (surfaceHolder) 
            {
                beginTime = System.currentTimeMillis();
                framesSkipped = 0;  // resetting the frames skipped
                // update game state 
                this.battleView.update();

                beginTime = System.currentTimeMillis();
                // render it
                this.battleView.render(canvas);             

                //... shortened
            }
        }
        finally 
        {
            if (canvas != null) 
            {
                surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }   // end finally
    }
}

}

2 个答案:

答案 0 :(得分:1)

我知道这是一个老帖子,但万一它可以帮助那些人。

我遇到了同样的问题,几乎与您的代码完全相同,并且发现我需要做的就是从我的SurfaceView中的重写postInvalidate()方法调用onDraw(Canvas canvas)

这是我的代码:

@Override
protected void onDraw(Canvas canvas)
{
   mPaperPlaneImage.draw(canvas);
   postInvalidate();
}

答案 1 :(得分:0)

您需要调用onDraw(Canvas画布)来渲染而不是渲染()因为onDraw适用于硬件屏幕缓冲区。检查第二个示例How can I use the animation framework inside the canvas?