0

在开始我目前正在开发的游戏之前,我构建了以下逻辑来处理暂停。那里的一切都很完美,至少我是这么想的。在测试应用程序中,逻辑仍然有效,这意味着我在其他地方打破了它。根据下面的逻辑和 LogCat 消息,您能指出我应该寻找的方向吗?我不知道如何解释下面的错误。任何帮助都会非常受欢迎。如果游戏进入睡眠状态,我不能完全要求重新启动游戏。

谢谢!

MainGamePanel.java

public void pause() {
    mSensorManager.unregisterListener(this);

}

public void resume(Context context) {
    mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);  
}

public void destroy() {
    thread.setRunning(false);

    if (thread != null)
    {
        Thread killThread = thread;
        thread = null;
        killThread.interrupt();
    }   

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    //continue the thread
    synchronized (thread) {
        thread.pleaseWait = false;
        thread.notifyAll();
    }

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    //pause the thread
    synchronized (thread) {
        thread.pleaseWait = true;
    }

}

主要活动:

//Restarts the accelerometer after onPause
protected void onResume() {
    super.onResume();
    viewPanel.resume(this);

}

//Standard Method run when the Application loses focus.
//This runs the pause() function in the viewPanel so that
//the accelerometer can be paused.
protected void onPause() {
    super.onPause();   
    viewPanel.pause();

}

protected void onDestroy() {
    super.onDestroy();
    viewPanel.destroy();
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
        // do something on back.
        viewPanel.backHit();
        return true;
    }

    return super.onKeyDown(keyCode, event);
}

还有我的 MainThread.java 文件:

    package com.petronicarts.stormthecastle;

import com.petronicarts.stormthecastle.MainGamePanel;

import android.graphics.Canvas;
import android.graphics.Matrix;
import android.view.SurfaceHolder;

public class MainThread extends Thread {

private SurfaceHolder surfaceHolder;
private MainGamePanel gamePanel;
private boolean running;
public boolean pleaseWait = true;
public void setRunning(boolean running) {
    this.running = running;
}

public MainThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {
    super();
    this.surfaceHolder = surfaceHolder;
    this.gamePanel = gamePanel;
}

@Override
public void run() 
{
    Canvas canvas;

    Matrix matrix = new Matrix();
    matrix.preScale(gamePanel.getScaleX(), gamePanel.getScaleY());
    long startTime, elapsedTime;
    startTime = System.currentTimeMillis();
    elapsedTime = System.currentTimeMillis() - startTime;

    while (running) {
        if(!pleaseWait) {
            canvas = null;

            // try locking the canvas for exclusive pixel editing on the surface
            try {
                canvas = this.surfaceHolder.lockCanvas();
                canvas.setMatrix(matrix);
                synchronized (surfaceHolder) {
                    // update game state
                    startTime = System.currentTimeMillis();
                    this.gamePanel.update(elapsedTime);

                    // draws the canvas on the panel
                    this.gamePanel.onDraw(canvas);

                    elapsedTime = System.currentTimeMillis() - startTime;

                }
            } finally {
                // in case of an exception the surface is not left in
                // an inconsistent state
                if (canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }   // end finally            
        }
        else {
            synchronized (this) {
                try {
                    wait();
                } catch (Exception e) { }
            }
        }
    }
}
}

LogCat 错误:

06-07 15:56:45.852: E/AndroidRuntime(3374):     FATAL EXCEPTION: main
06-07 15:56:45.852: E/AndroidRuntime(3374):     java.lang.NullPointerException
06-07 15:56:45.852: E/AndroidRuntime(3374):     at com.petronicarts.stormthecastle.MainGamePanel.surfaceDestroyed(MainGamePanel.java:312)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:600)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.SurfaceView.updateWindow(SurfaceView.java:486)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:213)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.View.dispatchDetachedFromWindow(View.java:6232)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.ViewRoot.dispatchDetachedFromWindow(ViewRoot.java:1868)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.ViewRoot.doDie(ViewRoot.java:2958)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.ViewRoot.die(ViewRoot.java:2928)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:254)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.Window$LocalWindowManager.removeViewImmediate(Window.java:445)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3201)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3306)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.app.ActivityThread.access$1600(ActivityThread.java:132)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1055)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.os.Looper.loop(Looper.java:150)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.app.ActivityThread.main(ActivityThread.java:4312)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at java.lang.reflect.Method.invokeNative(Native Method)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at java.lang.reflect.Method.invoke(Method.java:507)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at dalvik.system.NativeStart.main(Native Method)
4

1 回答 1

1

您可能不应该在线程变量上同步(在 中这样做surfaceDestroyed)。它设置为null别处(在 中destroy)。

实际上,一般来说,在非最终对象引用上进行同步总是一个坏主意。

于 2012-06-07T21:10:21.123 回答