2017-08-09 13 views
0

私のタイトルが私の質問を非常にうまく説明していないが、私はより良いものを見つけることができなかった。ハンドラが正しく動作しない

3つのボタンの開始、停止、リセット、および時間を表示するテキストビューを持つ単純なstopWatchアプリがあります。私の問題は、私はonClickStart方法でランナーを()コメントし、すべてがOKであるのonCreateメソッドでそれを置くときである

public class StopwatchActivity extends AppCompatActivity { 

private int mNumberOfSeconds = 0; 
private boolean mRunning = false; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_stopwatch); 
    //if if uncomment this runner method and delete the runner inside onClickStart everything will work find 
    //runner() 

} 

public void onClickStart(View view){ 
    mRunning = true; 
    runner(); 
} 

public void onClickStop(View view){ 
    mRunning = false; 
} 

public void onClickReset(View view){ 
    mRunning = false; 
    mNumberOfSeconds = 0; 

} 

public void runner(){ 
    final TextView timeView = (TextView) findViewById(R.id.time_view); 
    final Handler handler = new Handler(); 
    handler.post(new Runnable() { 
     @Override 
     public void run() { 
      int hours = mNumberOfSeconds/3600; 
      int minutes = (mNumberOfSeconds%3600)/60; 
      int second = mNumberOfSeconds%60; 
      String time = String.format("%d:%02d:%02d" , hours , minutes , second); 
      timeView.setText(time); 
      if (mRunning){ 
       mNumberOfSeconds++; 
      } 
      handler.postDelayed(this , 1000); 
     } 
    }); 

} 
} 

:アプリは、このようなただ一つの活性を有します。しかし、上記のようなコードを変更すると、コードはまだ実行されていますが、停止ボタンを押してからもう一度押すと、秒が4または5ずつ増加します。 誰もこの2つのモードの違いは何ですか?

+0

あなたが最初のランナーを殺すので、あなたがたときにタイマーを再起動していないで、第二走者が作成され、あなたのハンドラを宣言します。 mRunningの値だけをテストすると、最初のランナーは2番目のランナーだけでなく、もう一度カウントアップを開始します。 – Nick

+0

@ニックなぜrunner()をonCreateコードの中に置くとfindが動作するのですか?私はそれが同じシナリオだと思います –

+0

onCreateは一度しか実行されないので、ランナーのインスタンスを1つだけ起動するためです。 – Nick

答えて

1

は、グローバル

public void runner(){ 
    timeView = (TextView) findViewById(R.id.time_view); 
    handler = new Handler(); 
    runnable = new Runnable() { 
     @Override 
     public void run() { 
      int hours = mNumberOfSeconds/3600; 
      int minutes = (mNumberOfSeconds%3600)/60; 
      int second = mNumberOfSeconds%60; 
      String time = String.format("%d:%02d:%02d" , hours , minutes , second); 
      timeView.setText(time); 
      if (mRunning){ 
       mNumberOfSeconds++; 
      } 
      handler.postDelayed(this , 1000); 
     } 
    } 
    handler.post(runnable); 

} 

ボタン機能

public void onClickStart(View view){ 
    if(handler != null) { 
     //restart the handler to avoid duplicate runnable 
     handler.removeCallbacks(runnable);//or this handler.removeCallbacksAndMessages(null); 
    } 
    mRunning = true; 
    runner(); 
} 

public void onClickStop(View view){ 
    mRunning = false; 
    handler.removeCallbacks(runnable); // this will stop the handler from working 
} 
+0

私はこのコードを実行したいときと、アプリケーションが開始した後。開始ボタンを押すとヌルポインタ例外が発生します –

+0

ヌルオブジェクト参照で仮想メソッド 'void android.os.Handler.removeCallbacks(java.lang.Runnable)'を呼び出そうとしました –

+0

私はそれを修正しました。それを宣言するときにHandlerをインスタンス化するだけです。ありがとうございました –

関連する問題