Выполнение задачи в определенное время с использованием postDelayed - PullRequest
3 голосов
/ 18 июля 2011

Я хотел бы начать задание в определенное время.Для этого я использую runnable и postDelayed метод следующим образом:

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

            try {
                MY TASK
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
};

В моем коде я использую mLunchTask следующим образом:

mHandler = new Handler();
mHandler.postDelayed(mLaunchTask, myDelay*1000); 

и вычисляется myDelayследующим образом:

s  = DateFormat.format("hh:mm:ss aaa", d.getTime());
cTime = s.toString(); // current Time
ch = Integer.parseInt(cTime.substring(0,2)); // current hour
cm = Integer.parseInt(cTime.substring(3,5)); // current minute
cs = Integer.parseInt(cTime.substring(6,8)); // current second
if (cTime.substring(9,11).equalsIgnoreCase("pm") && (ch<12) ) ch = ch+12; 
myDelay=(desiredHour-ch)*3600+(desiredMinute-cm)*60 - cs;
if (myDelay<0) myDelay = 0;

и desiredHour и desiredMinute устанавливаются пользователем.Ожидается, что MY TASK начинается с desiredHour и desiredMinute и 0 секунд.Однако «МОЯ ЗАДАЧА начинается с задержкой в ​​несколько секунд, которая выглядит случайной.

Исходя из вышеприведенного кода, есть ли какая-либо причина, по которой он не запускается в нужное время?

Спасибо

Ответы [ 3 ]

5 голосов
/ 18 июля 2011

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

Calendar calendar = Calendar.getInstance();
long currentTimestamp = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR_OF_DAY, desiredHour);
calendar.set(Calendar.MINUTE, desiredMinute);
calendar.set(Calendar.SECOND, 0);
long diffTimestamp = calendar.getTimeInMillis() - currentTimestamp;
long myDelay = (diffTimestamp < 0 ? 0 : diffTimestamp);

Теперь у вас есть задержка в миллисекундах и вы можете запустить обработчик:

new Handler().postDelayed(mLaunchTask, myDelay);

В моем тесте следующеезапускаемые журналы в нужное время без задержки.

private Runnable mLaunchTask = new Runnable() {
    public void run() {
        Calendar calendar = Calendar.getInstance();
        Log.d("test", "started at " 
            + calendar.get(Calendar.HOUR_OF_DAY) + " " 
            + calendar.get(Calendar.MINUTE) + " "
            + calendar.get(Calendar.SECOND)
        );
    }
};

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

Может ли AlarmManager быть альтернативой?1014 *

0 голосов
/ 29 января 2012

Ответ Налибы не совсем правильный.

На основании документации, которую можно увидеть здесь видно, что этот класс специально используется для запуска задач в будущем.

"Существует дваОсновное использование для обработчика: (1) для планирования сообщений и исполняемых файлов, которые будут выполняться как некая точка в будущем , и (2) для постановки в очередь действия, которое будет выполнено в потоке, отличном от вашего

Нет никаких сведений о поведении приложения, когда система переходит в спящий режим, и эту проблему следует проверить перед публикацией дополнительной информации.

0 голосов
/ 07 октября 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...