Изменение системы Android синхронизирует таймеры остановок. Как я могу перезапустить их?

Я должен выполнить периодическую задачу в приложении 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

Ничто о прерываемом таймере, но это ясно больше не работает после того, как системные часы изменились. Мне нужна задача продолжать бежать все время, пока приложение работает.

Как я могу перезапустить таймер, если он останавливается как это? Нет никакого метода на Таймере или TimerTask, чтобы проверить, работает ли он в настоящее время, таким образом, я не могу знать, когда перенести его. Какие-либо идеи?

8
задан Alpha Hydrae 12 July 2010 в 08:54
поделиться

1 ответ

Я думаю, что есть несколько способов сделать это. В любом случае я бы не стал использовать таймер.

Вы можете использовать обработчик для запуска своей задачи в вызове 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);

Это будет поддерживать выполнение задачи, пока работает ваше приложение. Вы также можете настроить задержку в postDelayed в Runnable. Этот способ наполовину предсказуем, если вы сделаете еще один лупер.Использование основного потока может или не может быть подходящим в зависимости от задачи.

Существует также AlarmManager, к которому вы можете получить доступ через контекстный интерфейс, который предназначен для повторяющихся задач с более точными интервалами. Это немного сложнее в использовании, но вы получаете гибкость использования RTC и постоянных повторяемых задач.

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

Например, ожидающее намерение может инициировать широковещательное намерение, которое вы можете прослушать в другом месте. Вы можете создать это ожидающее намерение в onCreate вашего пользовательского объекта Application и отменить намерение в onTerminate ().

4
ответ дан 6 December 2019 в 00:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: