2012-06-24 1 views
0

Мне нужно выполнить код с интервалами, иногда 10 секунд, иногда 5 минут. Код должен быть выполнен на точных 10 секунд от начала, а затем в точных 5 минут и 10 секунд от начала и т.д.
хронометра тиканье вдоль находится с самого начала, так что время исполнение должно быть точным.Выполнить код в определенное время: Обработчик? AlarmManager?

Использование Handler.postDelayed не работает, потому что код для выполнения может занять некоторое время. Следующее выполнение кода может быть запоздалым, когда это произойдет.

Когда я хотел реализовать AlarmManager, я увидел записку

Сигнал тревоги менеджер предназначен для случаев, когда вы хотите, чтобы ваш код запуска приложения в определенное время, даже если ваше приложение не в настоящее время работает. Для обычных операций синхронизации (тики, таймауты, и т. Д.) Проще и эффективнее использовать Handler.

Итак, я немного смущен, как мне это сделать, чтобы гарантировать правильное выполнение?

ответ

1

Как заявил Крис, в Android нет такой вещи, как точное время.

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

некоторые псевдокод для ожидающих 5s:

class mJob implements Runnable{ 
    public void run(){ 
     while(System.currentTimeMillis()<myExactTime){ //poll for your time 
     Thread.sleep(1); 
     } 
     //Ok, we are as near as we'll ever get 
     //call here your 'realtime' function or whatever you need 
    } 
} 

mHandler.postDelayed(mJob,4950); //the closer to 5000, the better for the cpu but you could miss your `myExactTime` 

я сейчас не как точный это, вы просто должны попробовать. Но я не вижу другого способа стать более «реальным» с обычным SDK. Вы даже можете удалить sleep(1), чтобы стать еще ближе к вашему myExactTime.

Для следующего использования вызова что-то вроде этого (нуля):

nextCallDelayInMillis = starttimeInMillis+No1_Delay+No2_Delay-System.currentTimeMillis();

1

Посмотрите на это сообщение: Time/Date change listener. вы можете использовать метод setRepeating() или, альтернативно, снова установить таймер после каждого выполнения.

0

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

private Runnable mUpdateTimeTask = new Runnable() { 
public void run() { 

//some code 

mHandler.postDelayed(this, 1000); 
} 
}; 

Вот мой полный код, который я использовал postDelay для отображения таймера обратного отсчета: https://github.com/minimaldevelop/antistress/blob/master/src/com/minimaldevelop/antistress/AntiStressExerciseActivity.java

Кроме того, здесь я с помощью AlarmManger, но только до конца, чтобы отобразить сообщение на панели уведомлений при закрытии приложения.

1

Поскольку андроид не является оператором реального времени, точный сроки исполнения не могут быть без существенных модификаций ядра. Даже там, вы вряд ли на обычном устройстве для Android, чтобы иметь много способов точно ориентированных средств полезного ввода-вывода, поэтому просто запустить ваш код в идеальное время может быть недостаточно.

В лучшем случае вы можете определить использование более надежных таймеров в последней точке, в которой мог работать ваш код, и принять меры компенсации после факта.

С точки зрения доступных методов синхронизации, главное внимание должно быть уделено тому, что устройство предназначено для пробуждения от сна, чтобы выполнить события, и в этом случае вы должны использовать диспетчер аварийных сигналов, если вы намерены поддерживать пробуждение устройства в в каком случае вы должны использовать Wake Lock, или если вы в порядке со своими событиями, происходящими только тогда, когда устройство бодрствует, а ваша служба или активность запущена, в этом случае вы можете использовать простой таймер.

1

Вы не указали, если код выполняется во время работы приложения или в качестве фоновой службы. Это важно, потому что после того, как вы заблокировали свое устройство, Android переходит в спящий режим, где CPU выключен и функционирует, как postDelayed, не будет активирован. Усилия просят также начать работу. Будут транслироваться сообщения AlarmManager. Я процитирую из here

AlarmManager лучше всего использовать для задач, требующих перспективы, даже если приложение не открыто. Для нормальных операций синхронизации , которые должны выполняться во время использования приложения (тики, тайм-ауты и т. Д.), Более эффективны методы postDelayed() и postAtTime() для обработчика . AlarmManager требует слишком больших накладных расходов, чтобы оправдать это использование .