我正在为 Android 编写一个小游戏。游戏是使用线程在 SurfaceView 上绘制的。在 Thread 的 run() 方法中,我测试游戏是否结束,如果是,我尝试显示游戏结束对话框,但是这给了我前面提到的错误消息。我知道当非 UI 线程试图弄乱 UI 时会发生此错误。我想知道的是显示这样一个对话框的最佳方法。我已经粘贴了下面的代码。谢谢你的帮助:
public class BouncingBallActivity extends Activity{
private static final int DIALOG_GAMEOVER_ID = 0;
private BouncingBallView bouncingBallView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bouncingBallView = new BouncingBallView(this);
bouncingBallView.resume();
setContentView(bouncingBallView);
}
protected Dialog onCreateDialog(int id)
{
switch (id) {
case DIALOG_GAMEOVER_ID:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Game Over.")
.setCancelable(false)
.setPositiveButton("Try Again",
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface arg0,
int arg1)
{
bouncingBallView.resume();
}
})
.setNegativeButton("Exit",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which)
{
BouncingBallActivity.this.finish();
}
});
AlertDialog gameOverDialog = builder.create();
return gameOverDialog;
default:
return null;
}
}
class BouncingBallView extends SurfaceView implements Runnable
{
SurfaceHolder surfaceViewHolder;
Canvas canvas;
Context context;
Thread drawingThread;
boolean drawingThreadIsRunning;
boolean isInitialised;
Ball ball;
ArtificialIntelligence ai;
BouncingBallView(Context context)
{
//
}
public void pause()
{
isInitialised = false;
drawingThreadIsRunning = false;
boolean joiningWasSuccessful = false;
while(!joiningWasSuccessful)
try {
drawingThread.join();
joiningWasSuccessful = true;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void resume()
{
isInitialised = false;
drawingThread = new Thread(this);
drawingThread.setName("Drawing Thread");
drawingThreadIsRunning = true;
drawingThread.start();
}
public void run()
{
while(drawingThreadIsRunning)
{
if(!surfaceViewHolder.getSurface().isValid())
continue;
if(gameOver())
BouncingBallActivity.this.showDialog(DIALOG_GAMEOVER_ID);
try{
canvas = surfaceViewHolder.lockCanvas();
if(!isInitialised)init(canvas);
update();
surfaceViewHolder.unlockCanvasAndPost(canvas);
}catch(Exception e)
{
Log.e(BouncingBallActivity.this.toString(),String.format("%s: Just as the emperor had foreseen!\n(This error is expected. Canvas destroyed while animations continue.)", e.toString()));
}
}
}
private void init(Canvas canvas)
{
ball = new Ball(canvas, Color.GREEN);
ai = new ArtificialIntelligence(canvas, (int) (ball.getX()+100),canvas.getWidth());
isInitialised = true;
}
}
}