Если эта задача кажется разочаровывающей, возможно, это связано с тем, что это необычный вариант использования и несколько выходит за рамки того, что задумывали дизайнеры Android.Вы можете спросить себя, существует ли более «Android-подобный» способ достижения ваших целей (т. Е. без необходимости перечислять связанных клиентов).
Рассмотрим ваши требования:
- Плеер должен быть доступен, пока пользователь взаимодействует с приложением (через
Activity
) - Плеер должен продолжать существовать, пока приложение пользователя находится в фоновом режиме
- Плеер должен остановиться, когда пользователь нажмет на уведомление
- Приложение должно быть очищено, когда пользователь покончит с ним
Я думаю, что вы, возможно, выбралиначать воспроизведение с привязки к Service
и завершить воспроизведение с помощью onDestroy()
.Это ошибка проектирования, и она вызовет у вас много проблем.В конце концов, согласно docs , локальный внутрипроцессный Service
действительно просто представляет «желание приложения выполнить более продолжительную операцию, не взаимодействуя с пользователем», и оно «не являетсяозначает работу над основным потоком. "
Вместо этого, удерживая каждый Activity
в пределах между onStart()
и onStop()
, используя startService()
, когда начинается воспроизведение, и stopSelf()
когда игра останавливается, вы автоматически достигнете целей 1, 2 и 4. Когда приложение находится в состоянии, когда все Activities
находятся за пределами экрана, у него будет 0 связанных клиентов.Если, кроме того, startService()
не выдаются, это является кандидатом на немедленное завершение ОС.В любом другом состоянии ОС будет поддерживать его.
Это не требует какой-либо дополнительной причудливой логики для отслеживания границы Activities
.Конечно, вы, вероятно, захотите startForeground()
, когда игрок играет, и stopForeground()
, когда это будет сделано (вероятно, вы уже обработали эту деталь).
Это оставляет вопрос о том, как выполнитьЦель № 3.Чтобы изменить состояние в Service
из Activities
или из уведомления, вы можете просто использовать Intents
(так же, как вы уже).В этом случае Service
будет управлять своим жизненным циклом через stopSelf()
.Это предполагает, опять же, что вы используете startForeground()
в нужное время (Oreo +), иначе Android может завершить работу вашего приложения из-за пределов фонового выполнения .
Фактически,если вы решите использовать Intents
, вы можете обнаружить, что вам даже не нужно связывать свой Activities
с Service
(IOW, цель № 1 в данном случае не имеет значения).Вам нужно только связать с Service
, если вам нужна прямая ссылка на эту услугу (через Binder
).