Служба Android работает только при активном пользовательском интерфейсе
Похоже, что Android в последней версии ввел множество ограничений на запуск сервисов в фоновом режиме, что, конечно, является хорошей новостью для времени автономной работы наших устройств. Моя цель состоит в том, чтобы создать приложение, которое придерживается этого, только запуская службу, пока пользователь взаимодействует с приложением (что, по-видимому, и является целью). Но мне совсем не ясно, как вы можете правильно это реализовать. Мои требования следующие:
Служба должна быть запущена, как только любая активность станет видимой для пользователя.
Служба должна оставаться непрерывной в рабочем состоянии, пока пользователь взаимодействует с приложением (просмотр между действиями).
Когда пользовательский интерфейс (независимо от того, какое действие было активным) отправляется в фоновом режиме, служба должна работать в течение 2-3 секунд, а затем останавливаться. 2-3 секунды необходимо для полного отключения услуги.
Служба может быть запущена с помощью Push-сообщения, когда приложение находится в фоновом режиме (или закрыто), чтобы обрабатывать входящие события в любое время. Затем служба регистрируется на удаленном сервере и проверяет наличие обновлений. При наличии обновлений пользователю выдается уведомление. Затем служба снова отключается через 2-3 секунды бездействия.
Мне кажется, Bound Service - это то, что предназначено для использования. Но мне не ясно, как мои требования будут соответствовать модели Bound Service. Есть ли кто-нибудь, кто имеет какой-либо опыт с этим, кто может указать мне правильное направление?
РЕДАКТИРОВАТЬ: "Сервис" в этом случае является локальным, внутрипроцессного сервиса, который не предназначен для внешнего доступа.
1 ответ
(Этот ответ предполагает местное, "в процессе" Service
, что не вызывает сомнений, что вы собираетесь использовать.)
Для вашего случая использования вы фактически используете комбинацию методов, чтобы сохранить Service
Бег.
Используйте "связаны Service
модель "чтобы сохранить Service
в то время как любой из ваших Activities
видны Это достаточно просто; вызов bindService()
в Activity.onStart()
, а также unbindService()
в Activity.onStop()
, Если вы беспокоитесь о Service
разрушается в короткий момент перехода между двумя вашими Activities
не будь; Android достаточно умен, чтобы ждать изменений в жизненном цикле различных компонентов приложения, прежде чем он решит Service
не имеет ссылки / не требуется.
Вы должны использовать BIND_AUTO_CREATE
флаг для всех ваших bindService()
звонки. Имейте в виду, что Service
не создается сразу после звонка bindService()
; это займет несколько миллисекунд, и вы должны быть осторожны, чтобы вернуть управление в среду, возвращаясь из любого метода жизненного цикла (например, onStart()
) вы находитесь в настоящее время. Только тогда вы получите звонок onServiceConnected()
,
Вам нужно будет вручную отслеживать, сколько Activities
привязаны к вашему Service
, чтобы определить, когда начинать свою 2-3-секундную логику очистки. Смотрите этот ответ для правильного подхода. Не беспокойся о Service
быть уничтоженным синхронно во время вашего последнего unbindService()
вызов - так же, как с bindService()
фактическое изменение состояния жизненного цикла "задерживается".
Теперь вопрос в том, как вы храните Service
в течение этих дополнительных 2-3 секунд, в этот момент (точка, в которой вы определили количество открытых Activities
опустился до 0)? Ну, вы можете просто позвонить startService()
, Вы даже можете вызвать его из метода в вашем Service
подкласс; до тех пор, пока у вас есть действительный Context
доступно, это не имеет большого значения. startService()
указывает системе, что вы хотите сохранить Service
вокруг, независимо от того, сколько Activities
(или другие клиенты) могут быть связаны с этим. В этом случае Service
не будет перезапущен - он уже запущен!
После завершения очистки вы можете позвонить stopService()
или, еще лучше, stopSelf()
, Это эффективно отменяет startService()
позвоните, и скажет ОС: "Я сделал". Ожидайте звонок Service.onDestroy()
вскоре после этого.
Имейте в виду, что один из ваших Activities
может всплыть асинхронно и повторно привязать к Service
до завершения очистки. Это крайний случай, но тот, который легко обрабатывается. Service
будет уничтожено только в том случае, если выполняются оба этих условия: 1.) ни один клиент не будет привязан / привязан, и 2.) нет неотмененных вызовов startService()
существовать.
Обратите внимание, что в Oreo и более поздних версиях система может быть достаточно агрессивной, чтобы убивать приложения в фоновом режиме. Services
, Согласно этому документу, взаимодействие с пользователем помещает вас в белый список на "несколько минут", поэтому я думаю, что через 2-3 секунды все будет в порядке. Точно так же, если вы обрабатываете "высокоприоритетное сообщение FCM" (что, как я полагаю, вы подразумеваете под "push-сообщением"), вы попадете в белый список и получите еще несколько минут для выполнения Service
(на этот раз используя startService()/stopSelf()
подход).