2015年3月10日火曜日

【Android】【CountDownTimer】 0秒まで表示する (インターバルの挙動を調べてみる)

先日、CountDownTimer を用いたプログラムをつくってみました。

CountDownTimer クラスの基本的な使い方としては

CountDownTimer myCountDownTimer
               = new CowntDownTimer(long millisInFuture, long countDownInterval)

上記の様にインスタンス化の際に、カウントダウン時間(millisInFuture)、インターバル時間(countDownInterval)をミリ秒で渡します。

インターバル時間は、onTick()メソッドに記載した処理が行われる間隔になります。

秒単位のタイマーであれば、残り時間の表示を1秒に1回書き換えればいいので、インターバル時間は、1秒 = 1000ミリ秒の指定で問題ないように思われます。

しかし、実際に1000ミリ秒を指定すると、タイマー終了時の時間表示が“1”で止まってしまいます。

何故なのか解明するため、ログをとってみました。


ログの取り方

onTick()メソッド内に、下記の行を追加します。
onTick()毎に、残り時間がログに出力されます。

Log.i("MainActivity", "残り時間 = " + String.valueOf(millisUntilFinished));

インターバル時間を、1000, 100, 10, 1 と変えて、試してみました。

① 1000


② 100


③ 10


④ 1



これらから、以下の様に推測しました。

  • インターバルは、ミリ秒単位で正確に刻まれている訳ではなく、誤差がある。(1000, 100 ミリ秒インターバルでは、1回毎に10ミリ秒程度、10, 1 ミリ秒インターバルでは、1回毎に10~20ミリ秒程度)
  • 最後の1回の処理は飛ばされている?(④の1ミリ秒を除けば、もう1回処理されても良さそうな時間が残っているのに、されていない。)

これによって起こりそうな問題は、以下の2つが考えられます。


① 誤差による処理の抜け落ち

例えば、秒単位で時間を表示する場合、インターバルが1000ミリ秒だと、
1005 → 895 のようにonTickが刻まれてしまう可能性があり、その際は秒数の表示が 10 → 8 となり、9秒が抜け落ちる。

② 最後の秒(0秒)が表示されない

冒頭の通り。

これを防ぐためには、


 → 誤差を考慮に入れて、短めのインターバル時間を設定する。
 → これも考慮に入れて、さらに短めのインターバル時間を表示する...というのも手ですが、最後に表示する値は、onFinish()メソッドに記載する、とした方が、ムダが無く確実な気がします。

先日のカウントダウンタイマーの場合、以下の様にonFinish()内に、textViewに“0”を表示する処理を追記しました。
 
    // カウントダウン終了後の処理
        @Override
        public void onFinish() {
            toggleButton.setChecked(false); // toggleボタンをオフにする
            textView.setText("0"); // 0を表示
        }



0 件のコメント:

コメントを投稿