Android - CountDownTimer в ListView мерцает случайным образом

Я делаю listview с таймерами, каждый с различным сроком, в зависимости от базы данных (аналогично аукциону)

Time now = new Time();
now.setToNow();
now.normalize(true);
nowMillis = now.toMillis(true);
.
.

String endtime = a.get(position).get(TAG_ENDTIME);
Integer timeSecond = Integer.parseInt(endtime.substring(17, 19));
Integer timeMinute = Integer.parseInt(endtime.substring(14, 16));
Integer timeHour = Integer.parseInt(endtime.substring(11, 13));
Integer timeDay = Integer.parseInt(endtime.substring(0, 2));
Integer timeMonth = Integer.parseInt(endtime.substring(3, 5)) - 1;
Integer timeYear = Integer.parseInt(endtime.substring(6, 10));

Time future = new Time();
future.set(timeSecond, timeMinute, timeHour, timeDay, timeMonth, timeYear);
future.normalize(true);

long futureMillis = future.toMillis(true);
long interval = futureMillis - nowMillis;

new CountDownTimer(interval,1000)
{
 @Override
 public void onTick(long millisUntilFinished)
 {
 Long interval = millisUntilFinished;
 int days = (int) ((millisUntilFinished / 1000) / 86400);
 int hours = (int) (((millisUntilFinished / 1000) - (days * 86400)) / 3600);
 int minutes = (int) (((millisUntilFinished / 1000) - (days * 86400) - (hours * 3600)) / 60);
 int seconds = (int) ((millisUntilFinished / 1000) % 60);

 String countdown = String.format("%dd %dh %dm %ds", days, hours, minutes, seconds);
 holder.duration.setText(countdown);
 }

 @Override
 public void onFinish() 
 {
 // TODO Auto-generated method stub
 holder.duration.setText(TimeUp);
 }

}.start();

Этот код работает почти отлично, когда есть только один экземпляр.

Однако проблема возникает, когда имеется несколько экземпляров, одновременно работает 4-5 таймера

Несколько/все обратный отсчет начнут мерцать, будь то секунды, минуты, часы или дни.

например, один из моих мерцающих мерцаний между 27d 11h 54m 50s и 0d 23h 47m 0s

Поскольку это происходит как на эмуляторе, так и на моем устройстве, это, по-видимому, мой недостаток кода, но я не знаю, что может это сделать.

Я попытался изменить

holder.duration.setText(countdown) в holder.duration.setText(millisUntilFinished)

и обратный отсчет мерцает между желаемой продолжительностью и огромным случайным числом,

Пожалуйста помоги.

1 ответ

Вы должны использовать один TimerTask и поместить все свои обновления пользовательского интерфейса в этот единственный таймер, вместо этого запускать несколько CountDownTimer для по существу того же задания, поскольку вы уже выполняете всю математику, чтобы определить, когда "время вверх" для любого конкретного элемента, вы можете просто запустить один TimerTask и один раз в секунду обновить все. CountDownTimer полезен для подсчета единой реализации, потому что он выполняет некоторую встроенную математику и т.д. Вы переделываете всю эту математику, поэтому вы можете использовать один экземпляр регулярной TimerTask.

Реализация CountDownTimer передает запланированные задержки в обработке сообщений Handler. Один экземпляр обратного отсчета вряд ли приведет к каким-либо причудливым поведением, но если у вас есть несколько движений, все из которых должны "гадать", когда системные часы обращаются каждую секунду (время в миллисах заканчивается на "000" - один раз в секунду и все в то же время), то эти обработчики будут пытаться одновременно стрелять и неизбежно терпеть неудачу.

Если пользовательский интерфейс или другой процесс, вероятно, задерживают некоторые из этих сообщений, даже до того момента, когда он "пропустит тики", чтобы догнать. Кроме того, это означает, что следующая задержка сообщения может быть всего лишь в миллисекундах от следующего тика (т.е. Если она должна проверять каждые 1000 миллисекунд, но задерживается дополнительный миллион долларов, то она пропустит галочку, а также расписала следующее сообщение для 10 миллисов в будущем.

licensed under cc by-sa 3.0 with attribution.