Служба Android работает только при активном пользовательском интерфейсе - PullRequest
0 голосов
/ 23 января 2019

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

  • Служба должна быть запущена, как только любая активность станет видимой для пользователя.

  • Служба должна остаться непрерывно в рабочем состоянии, когда пользователь взаимодействует с приложением (просмотр между действиями).

  • Когда отправляется пользовательский интерфейс (независимо от того, какое действие было активным)в фоновом режиме, служба должна работать в течение 2-3 секунд, а затем остановить себя.Для полного отключения службы требуется 2-3 секунды.

  • Службу можно запустить с помощью Push-сообщения, когда приложение находится в фоновом режиме (или закрыто), чтобыобрабатывать входящие события в любое время.Затем служба регистрируется на удаленном сервере и проверяет наличие обновлений.При наличии обновлений пользователю выдается уведомление.Затем служба снова отключается через 2-3 секунды бездействия.

Мне кажется, что Связанная служба - это то, что предназначено для использования.Но мне не ясно, как мои требования будут соответствовать модели Bound Service.Есть ли кто-нибудь, кто имеет какой-либо опыт с этим, кто может указать мне правильное направление?

РЕДАКТИРОВАТЬ: «Служба» в этом случае является локальной, внутрипроцессной службы, которая не предназначена для доступавнешне.

1 Ответ

0 голосов
/ 23 января 2019

(Этот ответ предполагает локальное, «в процессе» Service, что, несомненно, то, что вы собираетесь использовать.)

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

Используйте "связанную * модель 1007 *", чтобы 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()).

...