1

Androidのキャンバスにいくつかのオブジェクトを拡張SurfaceViewして描画する例を作成しましたが、2つの問題に直面しています。Thread

  1. 戻るボタンを押すと、アプリケーションが閉じて、「残念ながら、例が停止しました」と表示されます。

  2. 向きを「縦」から「横」または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

私も同じ問題を抱えていました。解決策: 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);
                }
            }
于 2013-07-19T11:00:47.467 に答える