Я пишу небольшую игру для Android. Игра рисуется на SurfaceView с использованием потока. В методе run () потока я проверяю, закончилась ли игра, и если да, то я пытаюсь отобразить диалоговое окно «игра окончена», которое выдает мне вышеупомянутое сообщение об ошибке.
Я знаю, что эта ошибка возникает, когда поток не-пользовательский интерфейс пытается связываться с пользовательским интерфейсом. То, что я хотел бы знать, является лучшим подходом к отображению такого диалога. Я вставил код ниже.
Спасибо за вашу помощь:
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;
}
}
}