Amira Elsayed Ismail
Amira Elsayed Ismail

Reputation: 9414

SurfaceView crashes on surfaceChange Android

I have made an example that extend SurfaceView and Thread to draw some objects on canvas in Android but I'm facing two problems.

  1. When press back button the application closed and then show me that "Unfortunately, your example has stopped".

  2. When change the orientation from "Portrait" to "Landscape" or VS , the application failed to adjust the new screen and does not update the drawing then it is crash and show the same message "Unfortunately, your example has stopped".

Please review code:

@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
            }
        }
    }

When I check the logcat I found the following line that the problem in this part

@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
        }
    }

The problem in this line:

canvas = this.surfaceHolder.lockCanvas();

It is return null when change the orientation.

Upvotes: 1

Views: 3457

Answers (1)

Pommaniulo
Pommaniulo

Reputation: 21

I had the same problem. Solution: just check canvas for non null. In my tests:

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

Upvotes: 2

Related Questions