SurfaceView在SurfaceChange Android上崩溃

时间:2013-01-08 09:46:36

标签: android surfaceview

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

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

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

  3. 请查看代码:

    @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

1 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。解决方案:只检查canvas是否为null。 在我的测试中:

            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);
                }
            }