2012-03-27 49 views
0

我寫的一個小遊戲爲Android。遊戲是使用線程在SurfaceView上繪製的。在線程的run()方法,我測試看比賽就結束了,如果是,我嘗試但是顯示遊戲結束對話框,讓我forementioned錯誤消息。 我知道,當非UI線程嘗試混淆UI時會發生此錯誤。我想知道的是顯示這種對話的最佳方法。我粘貼了下面的代碼。 感謝您的幫助:當我展示遊戲結束對話框,我得到一個錯誤「無法創建內螺紋處理程序不叫Looper.prepare()」

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; 
     } 

    } 
} 

回答

2

嘗試這樣......你不能做任何修改後,從除各主要thread..put這部分你的線程內的其他UI如果(GAMEOVER())

//if(gameOver()) 
runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 

       BouncingBallActivity.this.showDialog(DIALOG_GAMEOVER_ID); 
      } 
     }); 
+0

感謝磨!工作就像一個魅力:) – 2012-03-27 12:16:41

+0

我遇到了一個問題,使用它。因爲它在線程內部,多個對話框不斷出現。有沒有辦法解決這個問題? – 2012-03-27 14:23:44

+0

在beginning..and聲明int變量你顯示對話一次之後..遞增它..和顯示等this..if(變量= 0)之前,檢查其值{BouncingBallActivity.this.showDialog(DIALOG_GAMEOVER_ID);可變++;} – 5hssba 2012-03-28 04:10:12

1

您正在從worker(後臺)線程調用Dialog。你需要從主線程調用它。嘗試使用Activity.runOnUIThread()調用它並在其中創建一個處理程序,它將調用您的showDialog方法。

0

我用[https://stackoverflow.com/a/16886486/3077964]解決問題。

你需要顯示runOnUiThread裏面的對話後暫停BouncingBallView的線程()。 那就是:

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

對我來說,我已經在我的surfaceView創建對話框使用該處理器。

Handler someHandler = new Handler(){ 
//this method will handle the calls from other threads. 
public void handleMessage(Message msg) { 

       final Dialog dialog = new Dialog(Game.this); 

        dialog.setContentView(R.layout.question_dialog); 
        dialog.setTitle("GAME OVER"); 




        Button restart=(Button)dialog.findViewById(R.id.btn Restart); 

        // Set On ClickListener 
        restart.setOnClickListener(new View.OnClickListener() { 

         public void onClick(View v) { 


           Toast.makeText(Game.this, "Restart Game", Toast.LENGTH_LONG).show(); 
           dialog.dismiss(); 

          } 


         } 
        }); 

        dialog.show(); 

      } 

因此,我在遊戲線程中寫入looper.prepared()來調用此Handler。如果玩家力量= 0,則此對話框將出現。

Looper.prepare(); 

//create the message for the handler 
Message status = someHandler.obtainMessage(); 
Bundle data = new Bundle(); 
String msgContent = null; 
data.putString("SOMETHING", msgContent); 
status.setData(data); 
someHandler.sendMessage(status); 

Looper.loop(); 

    }  
+0

按鈕重啓=(按鈕)dialog.findViewById(R.id.btnRestart); – Vetzehelza 2015-07-27 08:49:07

相關問題