2017-02-21 3 views
11

나는 countDownTimer를 가지고 있는데, 사용자가 12 초 내에 gameButton을 누르지 않으면 gameOver 메서드가 호출되기를 바란다. 문제 countDownTimer가 12이거나 타이머가 카운트 다운을 계속할 때 instamtly라고하는 게임 기능을 얻습니다. 그래서 postDelayed() 메서드를 사용하여 사용자에게 버튼을 두 번 누르고 countDownTimer를 계속 진행 시키겠다.하지만 지금은 코드가 맞으면 12 번에 상관없이 게임이 멈춘다.android studio에서 postDelayed()를 올바르게 사용하는 방법은 무엇입니까?

import android.app.Activity; 
import android.os.CountDownTimer; 
import android.os.Handler; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 
import android.widget.Toast; 



public class GameScreen extends Activity { 

    private TextView time; 
    private Button start; 
    private Button cancel; 
    private Button gameButton; 
    private CountDownTimer countDownTimer; 
    public static int count = 0; 
    public static int countFail = 0; 

    final Handler handler = new Handler(); 
    final Runnable r = new Runnable() { 
     public void run() { 
      handler.postDelayed(this, 1000); 
      gameOver(); 
     } 
    }; 


    private View.OnClickListener btnClickListener = new View.OnClickListener(){ 

     @Override 
     public void onClick(View v) { 

      switch(v.getId()){ 
       case R.id.start_ID : 
        start(); 
        break; 
       case R.id.cancel : 
        cancel(); 
        break; 
       case R.id.gameButton_ID : 
        gameButton(); 
        break; 
      } 

     } 


    }; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_game_screen); 


     start = (Button) findViewById(R.id.start_ID); 
     start.setOnClickListener(btnClickListener); 
     cancel = (Button) findViewById(R.id.cancel); 
     cancel.setOnClickListener(btnClickListener); 
     time = (TextView) findViewById(R.id.time); 
     gameButton = (Button) findViewById(R.id.gameButton_ID); 
     gameButton.setOnClickListener(btnClickListener); 


    } 

    public void start(){ 

     time.setText("16"); 
     //this doesnt work and makes app crash when you hit start button 

     countDownTimer = new CountDownTimer(16 * 1000, 1000) { 
      @Override 
      public void onTick(long millsUntilFinished){ 
       time.setText("" + millsUntilFinished/1000); 

       //turns textview string to int 
       int foo = Integer.parseInt(time.getText().toString()); 

       if(time.getText().equals("12")){ 

        r.run(); 

       } 

      } 

      public void onFinish() { 
       time.setText("Done !"); 
      } 
     }; 
     countDownTimer.start(); 
    } 

    private void cancel(){ 
     if(countDownTimer != null){ 
      countDownTimer.cancel(); 
      countDownTimer = null; 
     } 
    } 

    private void gameOver(){ 
     Toast.makeText(getApplicationContext(), "You scored " + count, Toast.LENGTH_SHORT).show(); 
     count = 0; 
     countFail = 0; 
     cancel(); 
    } 

    private void gameButton(){ 

     int foo = Integer.parseInt(time.getText().toString()); 

     if(foo % 2 == 0) { 
      Toast.makeText(getApplicationContext(), "PASS", Toast.LENGTH_SHORT).show(); 
      handler.removeCallbacks(r); 
      ++count; 
     } 

     else{ 
      gameOver(); 
     } 
    } 

} 

답변

26

거의 대부분 postDelayed(Runnable, long)을 사용하고 있습니다. Runnable을 살펴 보겠습니다. 우리가 r.run();를 호출 할 때

final Runnable r = new Runnable() { 
    public void run() { 
     handler.postDelayed(this, 1000); 
     gameOver(); 
    } 
}; 

는 할 것 첫 번째 것은 1000 밀리 초 후 Runnable를 매우 동일한를 실행하도록 handler에게 다음 gameOver()를 호출하는 것입니다. 이것이 실제로 발생하게되는 것은 gameOver() 메서드가 두 번 호출되는 것입니다. 바로 한 번 처리하고 1000 밀리 초를 기다린 후 두 번째로 처리합니다.

final Runnable r = new Runnable() { 
    public void run() { 
     gameOver(); 
    } 
}; 

을 그리고 다음과 같이 호출 :

대신에, 당신이 당신의이 Runnable를 변경해야이 도움이

handler.postDelayed(r, 1000); 

희망을.

+0

내가 필요한 것. 간단히 해체 해줘서 고마워. –

관련 문제