Я разрабатываю приложение, которое имеет повторяющуюся задачу отправки информации о присутствии на выделенный сервер, пока приложение находится на переднем плане.
При поиске в Интернете я увидел несколько различных подходов и хотел узнать, как лучше всего это сделать.
Как лучше всего запланировать вызов сервера?
Я видел следующие варианты:
Таймер .
Сервис .
BroadcastReciever с AlarmManager .
Каково ваше мнение?
EDIT:
причина, по которой мне это нужно, - это приложение на основе чата, которое отправляет все действия пользователя на удаленный сервер.
т.е. пользователь набирает сообщение, пользователь читает сообщение, пользователь в сети, пользователь не в сети и т. д.
Это означает, что один раз в каждом интервале мне нужно отправлять серверу, что я делаю, поскольку я открываю чат с другими людьми, они должны знать, что я делаю.
Подобно механизму обратной связи сообщений WhatsApp:
РЕДАКТИРОВАТЬ № 2:
повторяющиеся задачи теперь должны планироваться почти всегда через JobScheduler
API (или FirebaseJobDispatcher
для более низких API), чтобы предотвратить проблемы с разрядкой батареи, как можно прочитать в разделе жизненно важных функций обучения Android.
РЕДАКТИРОВАТЬ № 3:
FirebaseJobDispatcher устарел и заменен Workmanager , который также включает в себя функции JobScheduler.
источник
Ответы:
Я не уверен, но, насколько мне известно, я разделяю свои взгляды. Я всегда принимаю лучший ответ, если ошибаюсь.
Менеджер по тревоге
Менеджер аварийных сигналов удерживает блокировку пробуждения ЦП,
onReceive()
пока выполняется метод приемника аварийных сигналов . Это гарантирует, что телефон не перейдет в спящий режим, пока вы не завершите обработку трансляции. ПослеonReceive()
возврата диспетчер сигналов тревоги снимает эту блокировку пробуждения. Это означает, что в некоторых случаях телефон перейдет в спящий режим, как только вашonReceive()
метод завершится. Если ваш приемник будильника звонилContext.startService()
, возможно, телефон перейдет в спящий режим до запуска запрошенной службы. Чтобы предотвратить это, вашBroadcastReceiver
иService
нужно будет реализовать отдельную политику блокировки бодрствования , чтобы убедиться , что телефон продолжает работать , пока служба не станет доступной.Примечание. Диспетчер сигналов тревоги предназначен для случаев, когда вы хотите, чтобы код вашего приложения запускался в определенное время, даже если ваше приложение в данный момент не запущено. Для обычных операций с таймингом (тики, тайм-ауты и т. Д.) Проще и эффективнее использовать Handler.
таймер
Timer
имеет некоторые недостатки, которые устраняются с помощьюScheduledThreadPoolExecutor
. Так что это не лучший выборScheduledThreadPoolExecutor .
Вы можете использовать
java.util.Timer
илиScheduledThreadPoolExecutor
(предпочтительно), чтобы запланировать действие, которое должно происходить через регулярные промежутки времени в фоновом потоке.Вот пример использования последнего:
Так что я предпочел
ScheduledExecutorService
Но также подумайте о том, что если обновления будут происходить во время работы вашего приложения, вы можете использовать
Timer
, как предлагается в других ответах, или более новыйScheduledThreadPoolExecutor
. Если ваше приложение будет обновляться, даже если оно не запущено, вам следует использовать расширениеAlarmManager
.Обратите внимание, что если вы планируете обновлять, когда ваше приложение выключено, раз в десять минут это довольно часто и, следовательно, может быть слишком энергоемким.
источник
таймер
Как упоминалось в javadocs, вам лучше использовать ScheduledThreadPoolExecutor.
ScheduledThreadPoolExecutor
Используйте этот класс, когда ваш вариант использования требует нескольких рабочих потоков и интервал ожидания небольшой. Насколько маленький? Ну, я бы сказал минут 15.
AlarmManager
начинает планировать интервалы в это время , и это позволяет предположить , что для небольших интервалов сна можно использовать этот класс. У меня нет данных, подтверждающих последнее утверждение. Это догадка.обслуживание
Ваш сервис может быть закрыт ВМ в любой момент. Не используйте сервисы для повторяющихся задач. Повторяющаяся задача может запустить службу, что совсем другое дело.
BroadcastReciever с AlarmManager
Это лучший способ для более длительных интервалов сна (> 15 минут).
AlarmManager
уже есть constants (AlarmManager.INTERVAL_DAY
), предполагающие, что он может запускать задачи через несколько дней после первоначального планирования. Он также может разбудить ЦП для запуска вашего кода.Вы должны использовать одно из этих решений в зависимости от вашего времени и потребностей рабочего потока.
источник
Я понимаю, что это старый вопрос, и на него есть ответ, но это может кому-то помочь. В твоем
activity
В
onCreate
источник
Цитата из Планирования повторяющихся сигналов тревоги - документы о компромиссах :
Итак, исходя из этого, лучший способ запланировать вызов сервера - использовать Google Cloud Messaging (GCM) в сочетании с адаптером синхронизации .
источник
Я создал задачу вовремя, в которой задача, которую пользователь хочет повторить, добавить в метод Custom TimeTask run (). это успешно повторяется.
}
источник