I’m trying to make an Android game, and I am following a few code samples to get my game loop working. It involves making a new thread. In the run() method I have a try/finally block. After the finally block executes a NullPointerException is thrown. I have no idea why, nothing seems to be null and even if it is, nothing is referencing anything null. I thought maybe this was null but it doesn’t seem to be. Here’s the code I think is relevant:
public class MainThread extends Thread {
private boolean running;
private final SurfaceHolder holder;
private boolean GameIsRunning = false;
private int mMode;
public static final int STATE_LOSE = 1;
public static final int STATE_PAUSE = 2;
public static final int STATE_READY = 3;
public static final int STATE_RUNNING = 4;
public static final int STATE_WIN = 5;
private MainGame game;
public MainThread(SurfaceHolder holder, MainGamePanel panel) {
super();
this.holder = holder;
game = new MainGame(panel.getContext());
mMode = STATE_RUNNING;
}
@Override
public void run() {
while (running) {
Canvas c = null;
try {
c = holder.lockCanvas(null);
synchronized (holder) {
if (mMode == STATE_RUNNING) {
updateAll();
}
drawAll(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
holder.unlockCanvasAndPost(c);
}
} // <<<<<<<<<<<<< After this line executes a null pointer exception is thrown
}
}
Creation of thread:
public class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback{
private MainThread thread;
public MainGamePanel(Context context) {
super(context);
getHolder().addCallback(this);
// create the game loop thread
thread = new MainThread(getHolder(), this);
setFocusable(true);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}
Thanks!
The NPE is thrown inside the try block and becomes visible after the finally block has been executed.
From looking at the code, it happens most likely because
cisnullwhen you pass it toupdateAll. You have anullcheck inside the finally block – so I guess you expect that it may be null. Add another check in the try block and handlec == nullthere too.From the android API (
SurfaceHolder#lockCanvas):