9

Androidアプリケーションで定期的なタスクを実行する必要があります。私は現在、次のようなタイマーを使用しています。

final Handler guiHandler = new Handler();

// the task to run
final Runnable myRunnable = new Runnable() {

    @Override
    public void run() {
        doMyStuff();
    }
};

Timer timer = new Timer();
timer.schedule(new TimerTask() {

    @Override
    public void run() {
        guiHandler.post(myRunnable);
    }
}, 0, 30000); // run every 30 seconds

これは私が必要としていることを正確に実行しますが、問題があります。エミュレーターまたは電話で時刻を変更すると、タイマーが実行を停止します。これは、時間を変更したときにログに表示されるものです。

D/SystemClock(  331): Setting time of day to sec=1278920137
W/SystemClock(  331): Unable to set rtc to 1278920137: Invalid argument

タイマーが中断されることについては何もありませんが、システムクロックが変更された後は明らかにもう実行されません。アプリケーションが実行されている限り、常に実行し続けるタスクが必要です。

このように停止した場合、どうすればタイマーを再開できますか?TimerまたはTimerTaskには、現在実行されているかどうかを確認するメソッドがないため、いつ再スケジュールするかわかりません。何か案は?

4

1 に答える 1

4

これを行うにはいくつかの方法があると思います。どちらの場合もタイマーは使いません。

ハンドラーを使用して、postDelayed呼び出しでタスクを実行できます。その後、タスクはそれ自体の中からハンドラーにそれ自体を再登録する必要があります。

final int ONE_SECOND = 1000; // one second
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
   public void run() {
      ... // do some stuff
      if (expression) {
         handler.postDelayed(this, ONE_SECOND);
      }
   }
}, ONE_SECOND);

これにより、アプリが稼働している間、タスクが実行され続けます。Runnable内のpostDelayedで遅延率を調整することもできます。別のルーパーを作成する限り、この方法は半予測可能です。メインスレッドの使用は、タスクが何であるかによって適切な場合と適切でない場合があります。

コンテキストインターフェイスを介してアクセスできるAlarmManagerもあります。これは、より正確な間隔でタスクタスクを繰り返すためのものです。使用するのは少し複雑ですが、RTCと永続化された反復可能なタスクを使用できる柔軟性が得られます。

AlarmManager manager = mContext.getSystemService(Context.ALARM_SERVICE);
manager.setRepeating(AlarmManager.RTC, 
    <start_time_millis>, 
    <period_millis>, 
    pendingIntent);

たとえば、保留中のインテントは、他の場所で聞くことができるブロードキャストインテントを起動できます。このpendingintentは、カスタムApplicationオブジェクトのonCreateで作成し、onTerminate()でキャンセルできます。

于 2010-08-17T05:57:20.410 に答える