2017-12-24 10 views
0

ゲームが終了すると、警告ダイアログが表示され、ゲームが終了し、得られたスコアが表示されます。これは1回以上ですが、アプリがクラッシュするまでダイアログを開いたままにしています。私はなぜこれをやっているのか分かりません。 logcatはエラーを報告していません。私はtry {}でダイアログを開くコードを置こうとしましたが、それは時々動作しましたが一貫して動作しませんでした。問題の原因は何ですか?alertdialogが複数回開こうとしました

ここに関連コードがあります。

class SnakeView extends SurfaceView implements Runnable { 

public SnakeView(Context context, Point size){ 
    super(context); 
    handler = new Handler(context.getMainLooper()); 

    mContext = context; 

    mScreenWidth = size.x; 
    mScreenHeight = size.y; 

    mBlockSize = mScreenWidth/NUM_BLOCKS_WIDE; 
    mNumBlocksHigh = ((mScreenHeight))/mBlockSize; 

    loadSound(); 

    mHolder = getHolder(); 
    mPaint = new Paint(); 

    mSnakeXs = new int[200]; 
    mSnakeYs = new int[200]; 

    startGame(); 
} 
public void updateGame(){ 
    if (mSnakeXs[0]== mMouseXs && mSnakeYs[0] == mMouseYs){ 
     eatMouse(); 
    } 

    moveSnake(); 
    if (detectDeath()){ 
     mSoundPool.play(mDead_sound, 1, 1, 0, 0, 1); 

     final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext); 
     alertDialogBuilder 
       .setTitle("Game Over!") 
       .setMessage("Your score: " + mScore + "!") 
       .setCancelable(false) 
       .setPositiveButton("New", new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         Intent intent = new Intent(mContext, SnakeActivity.class); 
         mContext.startActivity(intent); 
        } 
       }) 
       .setNegativeButton("Exit", new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         Intent intent = new Intent(mContext, Start.class); 
         mContext.startActivity(intent); 
        } 
       }); 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 

       alertDialogBuilder.show(); 
      } 
     }); 


    } 


} 
private void runOnUiThread(Runnable r){ 
    handler.post(r); 
} 

    } 
+1

はそうし。 – ADM

+0

複数回呼び出された場合、 'if(detectDeath()&&!playerDead)'を使用し、ダイアログを表示する前に 'playerDead = true'を設定することができます。 –

+0

ダイアログを表示するかどうかを検出するブール値を含めることができます –

答えて

0

ダイアログを追跡する変数deadを紹介します。これは、プログラムがプログラムをクラッシュさせる可能性のあるOOM例外を引き起こす可能性のある新しいダイアログを作成するプロセス全体を通らないようにするためです。

class SnakeView extends SurfaceView implements Runnable { 
    boolean dead = false; 
    public SnakeView(Context context, Point size){ 
     super(context); 
     handler = new Handler(context.getMainLooper()); 

     mContext = context; 

     mScreenWidth = size.x; 
     mScreenHeight = size.y; 

     mBlockSize = mScreenWidth/NUM_BLOCKS_WIDE; 
     mNumBlocksHigh = ((mScreenHeight))/mBlockSize; 

     loadSound(); 

     mHolder = getHolder(); 
     mPaint = new Paint(); 

     mSnakeXs = new int[200]; 
     mSnakeYs = new int[200]; 

     startGame(); 
    } 
    public void updateGame(){ 
     if (mSnakeXs[0]== mMouseXs && mSnakeYs[0] == mMouseYs){ 
      eatMouse(); 
     } 

     moveSnake(); 
     if (detectDeath()&& !dead){ 
      mSoundPool.play(mDead_sound, 1, 1, 0, 0, 1); 

      final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext); 
      alertDialogBuilder 
        .setTitle("Game Over!") 
        .setMessage("Your score: " + mScore + "!") 
        .setCancelable(false) 
        .setPositiveButton("New", new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          Intent intent = new Intent(mContext, SnakeActivity.class); 
          mContext.startActivity(intent); 
         } 
        }) 
        .setNegativeButton("Exit", new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          Intent intent = new Intent(mContext, Start.class); 
          mContext.startActivity(intent); 
         } 
        }); 
      runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
    dead = true; 
        alertDialogBuilder.show(); 
       } 
      }); 


     } 


    } 
    private void runOnUiThread(Runnable r){ 
     handler.post(r); 
    } 

     } 
+0

ありがとうございます! – Tor99er

0

まあ、私はcontext.getMainLooper()は、すべてをループしているか、実行可能なロジックはちょうど自分自身に戻ってループしているかどうかわからないが、あなたがあなたのクラスhasDialogBeenShownにブールを宣言する可能性がでfalseに設定しましたSnakeView、そしてこれまで、あなたの実行を設定する()のコード:このような

public void run(){ 
    if(!hasDialogBeenShown){ 
     alertDialogBuilder.show(); 
     hasDialogBeenShown=true; 
    } 
} 

何かがあなたの問題を「解決」する必要がありますが、なぜalertDialogBu​​ilder.show()が実行可能でなければなりませんか?それはなぜUnnUiThreadを走らなければならないのですか?

+0

他の方法でもダイアログが表示されませんでした。これが私が見つけた唯一の方法でした。まあほとんど仕事:)。 – Tor99er

0

この削除:この置く

runOnUiThread(new Runnable() { 
@Override 
    public void run() { 
     alertDialogBuilder.show(); 
    } 
}); 

:あなたは `updateGame()`メソッドを複数回.DEBUGコードを呼び出し、その一度だけ呼び出すことを確認しているよう

final AlertDialog dialog2 = alertDialogBuilder.create(); 
dialog2.show(); 
+0

別のブール値は必要ありません。detectDeath()はtrueまたはfalseを返します。したがって、deadを使用しないでください –

関連する問題