When testing several games with a standard game thread in Android 4.0 it works well until the Activity is shut down (pressing the home button etc), leaving the activity the application crashes with a nullPointer.
This even happens in the sample LunarLander that Google has programmed.
The problem is that Canvas becomes null when leaving the activity and that makes the application crash.
The error message from the LogCat is just below.
02-27 18:07:58.974: V/MainThread(2667): CANVAS android.view.Surface$CompatibleCanvas@4102bcf0
02-27 18:07:59.164: V/MainThread(2667): CANVAS null
02-27 18:07:59.164: W/dalvikvm(2667): threadid=14: thread exiting with uncaught exception (group=0x409c01f8)
02-27 18:07:59.174: E/AndroidRuntime(2667): FATAL EXCEPTION: Thread-108
02-27 18:07:59.174: E/AndroidRuntime(2667): java.lang.NullPointerException
02-27 18:07:59.174: E/AndroidRuntime(2667): at com.joakimengstrom.pong.MainThread.run(MainThread.java:49)
This is the code when starting a thread, with the Log.v you see above.
while(this.running){
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
Log.v(TAG, "CANVAS " + canvas);
canvas.drawColor(Color.BLACK);
...
And below is when creating the thread and shutting it down when the surface is destroyed.
@Override
public void surfaceCreated(SurfaceHolder holder) {
thread = new MainThread(getHolder());
thread.setRunning(true);
thread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
How do I exit the thread in a safe way without making canvas null?
In Android 4.0,
SurfaceHolder.lockCanvascan returnnullwhen the surface is destroyed. So here:Just surround your
synchronized (surfaceHolder)block withif (canvas != null). This should not cause any issues with the behaviour of your application as it occurs when drawing is not needed.