Android CountDownTimer показывает 1 в течение двух секунд

Возможный дубликат:
Почему millisUntilFinished не может определить точные интервалы CountDownTimer?

Почему использование CountDownTimer показывает "1" дважды? Я просто хочу, чтобы он обратный отсчет плавно и не выглядел так, как будто он повесил трубку в последнюю секунду. У кого-нибудь есть идеи о том, как решить эту проблему?

Вот код со страницы разработчиков Android:

  new CountdownTimer(30000, 1000) {

     public void onTick(long millisUntilFinished) {
         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
     }

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();

Я создал новый проект и скопировал и вставлял этот код только для того, чтобы убедиться, что я случайно не использовал что-то в своей программе. Я тестировал это на вкладке 10.1. Он делает это, когда я запускаю его: "5", "4", "3", "2", "1", "1", "done!".

Ответы

Ответ 1

Функция CountDownTimer не является точной, она вернется как можно ближе к 1 секунде (в данном случае), но часто этого недостаточно, чтобы дать вам то, что вы хотите.

Если вы зарегистрируете ms var, вы увидите, что результат - это что-то вроде 29384 для первого удара и т.д., он никогда не будет 30000, 29000 и т.д. Невозможно получить точность, необходимую для создания счетчик работает так, как вы планировали в настоящее время.

Вы можете исправить это для большинства случаев. Сначала уменьшите свой интервал, чтобы получить больше обновлений, чем то, что вы хотите вывести, поэтому вместо 1 секунды сделайте 100 мс, и это даст вам иллюзии таймера обратного отсчета в 1 секунду, так как вы получите хотя бы несколько обновлений в секунду (худшее случай)

Чтобы оптимизировать этот бит вокруг результата для каждой записи и выполнить простую проверку, чтобы увидеть, нужно ли вам обновлять (изменилось значение секундLeft), и если он обновил пользовательский интерфейс и аккумулятор secondLeft. Также я предлагаю, чтобы onFinish дал окончательный результат (0) на всякий случай, когда система глючит, потому что происходит что-то, что ест циклы процессора.

В любом случае, это модифицированный код, который работает в течение 99.99 раз из 100, если ваша система не загружена сильно. ПРИМЕЧАНИЕ. Вероятно, вам удастся сэкономить 250 мс, до вас.

 int secondsLeft = 0; 

 new CountDownTimer(30000, 100) {
     public void onTick(long ms) {
         if (Math.round((float)ms / 1000.0f) != secondsLeft)
         {  
             secondsLeft = Math.round((float)ms / 1000.0f);
             TV.setText("seconds remaining: " +secondsLeft );
         }
         Log.i("test","ms="+ms+" till finished="+secondsLeft );
     }

     public void onFinish() {
         TV.setText("0");
     }
}.start();