ssummeraw 2013-04-15 02:00 采纳率: 10%
浏览 5199

Can't create handler inside thread has not called Looper.prepare() 错误

我在android环境下创建一个小游戏。这个游戏使用一个线程绘制在一个SurfaceView 上面。在线程的run()方法中,我测试看游戏是否结束,如果游戏结束就显示游戏结束对话框,但是却给出“Can't create handler inside thread has not called Looper.prepare()”的错误消息。我觉得是当一个非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;
        }

    }
}
  • 写回答

1条回答 默认 最新

  • nana4ever 2013-04-15 07:20
    关注

    除了主线程,在别的线程中不能做任何改变。在 if(gameOver()) 方法后把下面的代码放在你的线程中

    //if(gameOver())
     runOnUiThread(new Runnable() {
               @Override
               public void run() {
    
                   BouncingBallActivity.this.showDialog(DIALOG_GAMEOVER_ID);
               }
           });
    
    评论

报告相同问题?

悬赏问题

  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题
  • ¥15 Python时间序列如何拟合疏系数模型