Есть ли особенности жизненного цикла разных типов сервисов в Android
Что проверяют
Знаете ли вы, чем started и bound сервисы различаются по времени жизни и что изменилось в последних версиях Android. Следом спрашивают, когда сервис не нужен и работу правильнее отдать WorkManager.
Как отвечать
По типам:
- started: запускается через
startService()илиstartForegroundService():onCreate(), затемonStartCommand()на каждый запуск,onDestroy()послеstopSelf()илиstopService(). ВозвратonStartCommand()решает судьбу после убийства процесса:START_NOT_STICKYне перезапускает,START_STICKYперезапускает сnullвместо intent,START_REDELIVER_INTENTдоставляет последний intent заново; - bound: создаётся через
bindService(), получаетonBind()и живёт, пока привязан хотя бы один клиент, потомonUnbind()иonDestroy(). ЕслиonUnbind()вернулtrue, новая привязка придёт вonRebind(); - смешанный: запущен и привязан одновременно, останавливается только после
stopSelf()и отвязки всех клиентов; - foreground: тот же started-сервис с уведомлением. После
startForegroundService()нужно за несколько секунд вызватьstartForeground(), иначе приложение упадёт. Для свежегоtargetSdk: с Android 12 его почти нельзя запустить из фона, с Android 14 обязателенforegroundServiceTypeи разрешение под тип, с Android 15 уdataSyncесть лимит времени и колбэкonTimeout().
Отдельного типа «background service» нет: это started-сервис без уведомления, и с Android 8 система останавливает его вскоре после ухода приложения в фон. Отложенную гарантированную работу отдают WorkManager, сервис оставляют для того, что пользователь видит сейчас: плеер, навигация, звонок.
Где спотыкаются
Думают, что сервис работает в отдельном потоке. Колбэки идут в главном, тяжёлая работа там даёт ANR, нужны свои корутины, например lifecycleScope в LifecycleService.
Считают, что foreground-сервис неубиваем. Приоритет у него высокий, но при острой нехватке памяти или из диспетчера задач его тоже завершают.
Забывают вызвать stopSelf(), когда работа закончена. Сервис держит процесс и тратит батарею. У bound-сервиса зеркальная ошибка: забытый unbindService() и утечка ServiceConnection.