(Этот ответ предполагает локальное, «в процессе» 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()
).