Я должен выполнить периодическую задачу в приложении 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, чтобы проверить, работает ли он в настоящее время, таким образом, я не могу знать, когда перенести его. Какие-либо идеи?
Я думаю, что есть несколько способов сделать это. В любом случае я бы не стал использовать таймер.
Вы можете использовать обработчик для запуска своей задачи в вызове 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 ().