2013-04-02 3 views
0

Мое намерение состоит в создании таймера, который начинается с 00:00:00 и висит вместе с функцией записи. Эта запись выполняется в службе , поэтому таймер также находится в той же службе. Если приложение перемещается в фоновый режим, запись и, следовательно, таймер продолжаются, и приложение выбирает время в onResume с помощью myService.getTime().Функция таймера в сервисе (вид хронометра)

Но я испытываю две странные вещи. Первый заключается в том, что мой таймер иногда проходил быстрее, чем секунда, иногда медленнее, иногда перескакивает с 00:00:04 до 00:00:06 и т. Д. Существует нет согласия. Я использую код ниже, но может быть лучший вариант для решения этой проблемы? Второй заключается в том, что он вызывает лаг на моей кнопке, хотя я запускаю ее в сервисе?

СЕРВИС

//////////TIMER FUNCTION START////////// 

     private void startTimerClick() { 

      if (stopped) { 
       startTime = System.currentTimeMillis() - elapsedTime; 
      } else { 
       startTime = System.currentTimeMillis(); 
      } 
      mHandler.removeCallbacks(startTimer); 
      mHandler.postDelayed(startTimer, 0); 

     } 

     private void pauseTimerClick() { 
      mHandler.removeCallbacks(startTimer); 
      stopped = true; 

     } 

     private void stopTimerClick() { 
      mHandler.removeCallbacks(startTimer); 
      stopped = false; 

     } 

     private void startTimer() { 

      startTimer = new Runnable() { 
       public void run() { 
        elapsedTime = System.currentTimeMillis() - startTime; 
        updateTimer(elapsedTime); 
        mHandler.postDelayed(this, REFRESH_RATE); 
       } 
      }; 

     } 

     private void updateTimer(float time) { 
      secs = (long) (time/1000); 
      mins = (long) ((time/1000)/60); 
      hrs = (long) (((time/1000)/60)/60); 

      /* 
      * Convert the seconds to String and format to ensure it has a leading 
      * zero when required 
      */ 
      secs = secs % 60; 
      seconds = String.valueOf(secs); 
      if (secs == 0) { 
       seconds = "00"; 
      } 
      if (secs < 10 && secs > 0) { 
       seconds = "0" + seconds; 
      } 

      /* Convert the minutes to String and format the String */ 

      mins = mins % 60; 
      minutes = String.valueOf(mins); 
      if (mins == 0) { 
       minutes = "00"; 
      } 
      if (mins < 10 && mins > 0) { 
       minutes = "0" + minutes; 
      } 

      /* Convert the hours to String and format the String */ 

      hours = String.valueOf(hrs); 
      if (hrs == 0) { 
       hours = "00"; 
      } 
      if (hrs < 10 && hrs > 0) { 
       hours = "0" + hours; 
      } 


     } 
     //////////TIMER FUNCTION END//////////// 


    public String getHours(){ 

     return hours; 
    } 

    public String getMinutes(){ 

     return minutes; 
    } 

    public String getSeconds(){ 

     return seconds; 
    } 
} 

АКТИВНОСТЬ (/ ФРАГМЕНТ)

private void timerStart() { 

     handler = new Handler(); 
     Thread t = new Thread() { 

       @Override 
       public void run() { 
       try { 
        while (!isInterrupted()) { 
        Thread.sleep(1000); 
        handler.post(new Runnable() { 
         @Override 
         public void run() { 

          timer.setText(myService.getHours()+":"+myService.getMinutes()+":"+myService.getSeconds()); 
         } 
        }); 
        } 
       } catch (InterruptedException e) { 
       } 
       } 
      }; 

      t.start(); 

    } 

ответ

0

Вы используете темы, как в вашей службе и в коде активности/фрагмента. Использование потоков для задач, чувствительных к времени в Android, является проблемой, поскольку Android способен значительно задерживать потоки.

Я использовал ScheduledThreadPoolExecutor для аналогичной задачи, и он отлично поработал.

Вы затем использовать его как это:

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); // where 1 is the number of needed concurrent threads. 1 should last for your needs. 
executor.scheduleWithFixedDelay(new TimerTask() { 
    // your recurringly executed code here 
}, 0, 1, TimeUnit.SECONDS); 
+0

бы также быть решением для сохранения StartTime в службе, и сделать саму синхронизацию только в основной деятельности/фрагмента? @ hoelle2011 –

+0

Я предполагаю, что вы используете эту услугу, чтобы поддерживать свое приложение в фоновом режиме. Конечно, можно сохранить время начала в члене службы, но, возможно, другое место будет более подходящим. Если вам нужен таймер для любой другой фоновой задачи, вы должны, вероятно, сохранить его в службе. Подумайте о таких задачах, как создание уведомления через определенное время - даже если ui не отображается и, следовательно, таймер в действии/фрагменте может не выполняться. – hoelle2011