android - SurfaceView 在 surfaceChange Android 上崩溃

标签 android surfaceview

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

  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

最佳答案

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

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

关于android - SurfaceView 在 surfaceChange Android 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14212165/

相关文章:

android - 在 Android 应用程序中访问 Whatsapp Media 文件夹

android - 在 Surfaceview 的 Canvas 上显示位图

android - 在 GameThread (android) 中开始由 bool 值触发的新 Activity

android - Dialog(或具有 Theme.Dialog 的 Activity)内的 SurfaceView 存在布局故障

android - 媒体播放器完成后如何清除表面支架?

android - 在 android 的下一个 Activity 的 videoView 中传输录制的摄像机视频(使用 Media Recorder)

android - 如何在我的项目结构中设置位置?

android - float 操作按钮不会出现在 < 5 android 版本的设备上

android - 如何使用JNI将数据从 native c二进制传递到android模型?

android - Adb 突然停止工作