1

我做了一个例子,在 Android 的画布上扩展SurfaceViewThread绘制一些对象,但我面临两个问题。

  1. 当按下后退按钮时,应用程序关闭,然后显示“不幸的是,您的示例已停止”。

  2. 当将方向从“Portrait”更改为“Landscape”或 VS 时,应用程序无法调整新屏幕并且不会更新绘图,然后它会崩溃并显示相同的消息“不幸的是,您的示例已停止”。

请查看代码:

@Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO implement this method
        holder.getSurface().setSize(width, height);
        holder.setFormat(format);
    }    

@Override
    public void surfaceCreated(SurfaceHolder holder) {
        // at this point the surface is created and
        // we can safely start the game loop
        thread.setRunning(true);
        thread.start();
    }

@Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        // tell the thread to shut down and wait for it to finish
        // this is a clean shutdown
        boolean retry = true;
        while (retry) {
            try {
                thread.join();
                retry = false;
            } catch (InterruptedException e) {
                // try again shutting down the thread
            }
        }
    }

当我检查 logcat 时,我发现以下行表明这部分的问题

@Override
    public void run() {
        Canvas canvas;
        // initialise timing elements for stat gathering
        initTimingElements();

        long beginTime; // the time when the cycle begun
        long timeDiff; // the time it took for the cycle to execute
        int sleepTime; // ms to sleep (<0 if we're behind)
        int framesSkipped; // number of frames being skipped

        sleepTime = 0;

        while (running) {
            canvas = null;
            // try locking the canvas for exclusive pixel editing
            // in the surface
            try {
                canvas = this.surfaceHolder.lockCanvas();
                LoggerHandler.log("canvas : " + canvas);
                synchronized (surfaceHolder) {
                    beginTime = System.currentTimeMillis();
                    framesSkipped = 0; // resetting the frames skipped
                    // update game state
                    this.gamePanel.update();
                    // render state to the screen
                    // draws the canvas on the panel
                    this.gamePanel.render(canvas);
                    // calculate how long did the cycle take
                    timeDiff = System.currentTimeMillis() - beginTime;
                    // calculate sleep time
                    sleepTime = (int) (FRAME_PERIOD - timeDiff);

                    if (sleepTime > 0) {
                        // if sleepTime > 0 we're OK
                        try {
                            // send the thread to sleep for a short period
                            // very useful for battery saving
                            Thread.sleep(sleepTime);
                        } catch (InterruptedException e) {
                        }
                    }

                    while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
                        // we need to catch up
                        this.gamePanel.update(); // update without rendering
                        sleepTime += FRAME_PERIOD; // add frame period to check
                                                    // if in next frame
                        framesSkipped++;
                    }

                    // for statistics
                    framesSkippedPerStatCycle += framesSkipped;
                    // calling the routine to store the gathered statistics
                    storeStats();
                }
            } finally {
                // in case of an exception the surface is not left in
                // an inconsistent state
                if (canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            } // end finally
        }
    }

这一行的问题:

canvas = this.surfaceHolder.lockCanvas();

null改变方向时返回。

4

1 回答 1

2

我有同样的问题。解决方案:只需检查画布是否为非空。在我的测试中:

            try {
                canvas = surfaceHolder.lockCanvas(null);
                if(canvas != null){
                    synchronized (surfaceHolder) {
                        canvas.drawColor(Color.BLACK);
                        canvas.drawBitmap(picture, 0, 0 , null);
                    }
                }
            } 
            finally {
                if (canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
于 2013-07-19T11:00:47.467 回答