2013-04-02 82 views
0

我的意圖是創建一個從00:00:00開始並與記錄功能一起掛起的計時器。此記錄在服務中完成,因此,計時器也處於相同的服務中。如果應用程序移動到後臺,錄製和定時器繼續執行,應用程序會使用myService.getTime()在onResume中選擇時間。服務中的計時器功能(類型的計時器)

但我經歷了兩件奇怪的事情。 第一個是我的計時器有時比一秒鐘快,有時慢,有時從例如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

難道也是爲了節省開始時間在服務的解決方案,並做只是在主要活動/片段的時間本身? @ hoelle2011 –

+0

我想你在後臺操作時使用該服務來保持你的應用程序活着。當然,可以將服務開始時間保存在服務成員中,但也許另一個地方可能更合適。如果你需要定時器來處理其他後臺任務,那麼你應該把它保留在服務中。考慮一些任務,比如在一段時間後創建通知 - 即使ui不可見,因此activity/fragment中的計時器可能不會執行。 – hoelle2011