2016-09-03 8 views
-4

私は毎分UI要素を更新するためにタイマを実行するAndroid Activityのコードをいくつか持っています。タイマーを起動するコードは(onResumeに呼び出された)このように:タイマースケジュールが奇妙な数字になっています

 timerTask = new TimerTask() { 
      @Override 
      public void run() { 
       runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         updateUtc(); 
        } 
       }); 
      } 
     }; 
     // update the time at the next time the minute rolls over 
     long delay = 61000 - System.currentTimeMillis() % 60000L; 
     timer.scheduleAtFixedRate(timerTask, delay, 60000L); 

私は例外をスロー野生でこのアプリからエラーが記録されています:

java.lang.IllegalArgumentException: Illegal delay to start the TimerTask: -1560105959000 
at java.util.Timer.scheduleImpl(Timer.java:567) 
at java.util.Timer.scheduleAtFixedRate(Timer.java:528) 

私はどのように自分のコードを参照することはできませんそのような大きな負の数を生成した可能性があります。 currentTimeMillis()が負の数を返しても、計算全体の結果は依然として正の値になります。私は何か見落としていますか?

+0

あなたは、onresumeがトリガーされるたびに新しい時間タスクを作成するとは思わないでしょうか?悪いですね? –

+0

@PavneetSinghもちろん、新しいタスクを作成します。アクティビティが一時停止しているときにタイマーを実行したくないので、TimerTaskは 'onPause()'で取り消されます。キャンセルされたTimerTaskは再利用できないため、毎回新しいTimerTaskを作成する必要があります。 Timer(OTOH)はonCreate()で作成され、onDestroy()でキャンセルされます。 – Clyde

+0

は 'long delay = 61000 - System.currentTimeMillis()%60000L;'が負の値 –

答えて

1

まあ、私は答えを見つけました。例外のテキストは誤解を招くものです。

long when = delay + System.currentTimeMillis(); 

     if (when < 0) { 
      throw new IllegalArgumentException("Illegal delay to start the TimerTask: " + when); 

そこで印刷される値は、遅延が、現在のシステム時間に遅延を追加することによって算出された絶対時間ではない:scheduleAtFixedRateImpl()のコードは次のようになります。システムの日付が1970より前に設定されている場合、currentTimeMillis()は負の数を返します。したがって、短い答えは、デバイスが1970年より前の日付を持っている場合、Androidのタイマー機能を使用できないことです。

0

モジュロは減算の前に処理されると思います。だからこれはトリックを行うかもしれません:

(61000 - System.currentTimeMillis()) % 60000L 
+0

モジュロは、角かっこなしでも優先される必要があります。 – earthw0rmjim

関連する問題