在Android 4.0中使用标准游戏线程测试多个游戏时,它会很好地运行,直到Activity关闭(按下主页按钮等),使应用程序崩溃并返回nullPointer。
这甚至发生在Google编程的LunarLander示例中。
问题是Canvas在离开活动时变为null,这会导致应用程序崩溃。
来自LogCat的错误消息就在下面。
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)
这是启动线程时的代码,使用上面的Log.v。
while(this.running){
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
Log.v(TAG, "CANVAS " + canvas);
canvas.drawColor(Color.BLACK);
...
下面是创建线程并在表面被破坏时关闭它。
@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) {
}
}
}
如何在不使canvas为null的情况下以安全的方式退出线程?
答案 0 :(得分:8)
在Android 4.0中,SurfaceHolder.lockCanvas
可在表面被销毁时返回null
。所以这里:
try {
canvas = this.surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
Log.v(TAG, "CANVAS " + canvas);
canvas.drawColor(Color.BLACK);
用synchronized (surfaceHolder)
围绕if (canvas != null)
块。这不应该导致应用程序行为出现任何问题,因为在不需要绘图时会发生这种问题。