Устранение неполадок служб переднего плана

На этой странице рассматриваются некоторые распространенные причины сбоев в работе служб переднего плана и предлагается помощь в определении источника проблемы.

В данном документе рассматриваются следующие вопросы:

Перед началом устранения неполадок

Проверьте наличие последних изменений в работе служб переднего плана.

Неправильное использование служб переднего плана может негативно сказаться на производительности устройства и времени автономной работы. Поэтому в новых версиях платформы Android часто вносятся изменения в поведение служб переднего плана, чтобы ограничить эти негативные последствия.

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

  • Код фоновой службы, который ранее работал исправно, теперь не работает.
  • You have just started testing on a new platform release, or you have changed the API level targeted by your app

Кроме того, если вы тестируете свое устройство на предварительной версии платформы для разработчиков, обязательно ознакомьтесь с самой последней версией документации для этой версии .

Ошибки "Приложение не отвечает" (ANR)

При определенных обстоятельствах приложение должно завершить работу своей фоновой службы. Если приложение этого не делает, система останавливает службу и вызывает ошибку "Приложение не отвечает" (ANR).

Слишком короткие рейсы приводят к ANR (отсутствию аварийного восстановления).

Сервисы переднего плана, использующие короткий тип обслуживания , должны завершиться быстро, примерно за три минуты. По истечении этого времени система вызывает метод Service.onTimeout(int,int) сервиса. У сервиса есть несколько секунд, чтобы вызвать stopSelf() . Если сервис не остановится, система выдаст ошибку «Приложение не отвечает».

Диагноз :

Если ошибка ANR вызвана тем, что служба переднего плана не остановилась, система генерирует внутреннее исключение. Вы можете убедиться в этом, проверив отчеты об ошибках ANR. Если проблема именно в этом, в отчете будет содержаться следующее сообщение:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type FOREGROUND_SERVICE_TYPE_SHORT_SERVICE did not stop within its timeout:
[component name]"

Исправить :

Убедитесь, что все временные службы переднего плана завершили свою работу и вызвали stopForeground(int) в течение установленного системного лимита времени.

Убедитесь, что ваши службы переднего плана реализуют Service.onTimeout(int,int) . Убедитесь, что ваша реализация этого метода вызывает stopSelf() сразу же.

Исключения для служб переднего плана

В этом разделе описаны несколько проблем, связанных с работой служб переднего плана, которые могут привести к возникновению исключения в системе. Если приложение не перехватывает исключение, пользователь видит диалоговое окно, сообщающее о том, что приложение остановлено.

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

Внутреннее исключение: Превышено время ожидания

Система устанавливает ограничение на продолжительность работы служб синхронизации данных и обработки мультимедиа в фоновом режиме, пока приложение находится в фоновом режиме. Если служба превышает это ограничение, система вызывает метод Service.onTimeout(int,int) . У службы есть несколько секунд, чтобы вызвать stopSelf() . Если служба не останавливается, система генерирует внутреннее исключение RemoteServiceException , что приводит к сбою приложения.

Диагноз :

Вы можете узнать, в чём заключалось исключение, посмотрев трассировку стека , а для получения более подробной информации об ошибке можно обратиться к Logcat . В данном случае Logcat выдаёт следующее сообщение об ошибке:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type [service type] did not stop within its timeout: [component name]"

Исправить :

Убедитесь, что все временные службы переднего плана завершили свою работу и вызвали stopForeground(int) в течение установленного системного лимита времени.

Убедитесь, что ваши службы переднего плана реализуют Service.onTimeout(int,int) . Убедитесь, что ваша реализация этого метода вызывает stopSelf() сразу же.

Внутреннее исключение: ForegroundServiceDidNotStartInTimeException

При запуске службы с помощью вызова context.startForegroundService() у этой службы есть несколько секунд, чтобы перейти в режим работы на переднем плане, вызвав ServiceCompat.startForeground() . Если служба этого не сделает, будет выброшено внутреннее исключение ForegroundServiceDidNotStartInTimeException .

Диагноз :

Вы можете узнать, в чём заключалось исключение, посмотрев трассировку стека , а для получения более подробной информации об ошибке можно обратиться к Logcat . В данном случае Logcat выдаёт следующее сообщение об ошибке:

android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
Context.startForegroundService() did not then call Service.startForeground()

Исправить :

Убедитесь, что все вновь созданные службы переднего плана вызывают метод ServiceCompat.startForeground() в течение нескольких секунд.

Менеджер работ :

Это исключение также может наблюдаться у рабочих процессов WorkManager , которые выполняют службу переднего плана (вызывают setForegound или setForegroundAsync ). Когда жизненный цикл двух рабочих процессов переднего плана пересекается, и один из них пытается запустить службу переднего плана, в то время как ранее запущенная служба переднего плана пытается завершить работу, это приведет к сбою, сопровождаемому следующим сообщением в журнале:

Re-initializing SystemForegroundService after a request to shut-down

A fix for this crash was introduced in WorkManager version 2.10.5 .

Если в вашем приложении возникает это исключение, обновите WorkManager до последней версии и сообщите о любых сохраняющихся проблемах в систему отслеживания ошибок WorkManager.

ForegroundServiceStartNotAllowedException

Ошибка :

Система выдает исключение ForegroundServiceStartNotAllowedException .

Причина :

Обычно это происходит из-за того, что приложение запускает фоновую службу в фоновом режиме, когда для этого нет соответствующего исключения.

Начиная с Android 12 (уровень API 31), приложениям запрещено запускать службы переднего плана, пока приложение работает в фоновом режиме , за некоторыми исключениями . Если вы попытаетесь запустить службу переднего плана из фонового режима и не выполните требования одного из исключений, система выдаст исключение ForegroundServiceStartNotAllowedException . Система также выдаст это исключение, если вы не выполните требования соответствующего исключения.

Например, в приложении может быть кнопка, нажатие которой запускает обработку данных и затем запускает службу переднего плана. В этом случае существует опасность того, что пользователь, нажав кнопку, немедленно переведет приложение в фоновый режим. Затем приложение попытается запустить службу из фонового режима. Если приложение не соответствует одному из указанных исключений, система выдает исключение ForegroundServiceStartNotAllowedException .

Кроме того, некоторые исключения имеют короткий срок действия. Например, существует кратковременное исключение, если ваше приложение запускает службу переднего плана в ответ на сообщение FCM с высоким приоритетом. Если вы не запустите службу достаточно быстро, вы получите исключение ForegroundServiceStartNotAllowedException .

В новых версиях Android некоторые исключения иногда становятся более строгими. Если вы изменили целевую версию Android для своего приложения, проверьте документацию по изменениям в работе служб переднего плана и убедитесь, что ваше приложение по-прежнему соответствует одному из разрешенных исключений.

Исправить :

Измените рабочий процесс вашего приложения таким образом, чтобы ему не требовалось запускать службы переднего плана, пока приложение работает в фоновом режиме, или убедитесь, что ваше приложение соответствует одному из исключений.

Вы можете использовать компоненты, учитывающие жизненный цикл , чтобы управлять жизненным циклом вашего приложения и избежать непреднамеренной попытки запуска службы переднего плана из фонового режима.

SecurityException

Ошибка :

Система выдает исключение SecurityException .

Причина :

Ваше приложение попыталось запустить службу переднего плана, не имея необходимых разрешений.

  • Если приложение ориентировано на Android 9 (уровень API 28) или выше, оно должно иметь разрешение FOREGROUND_SERVICE для запуска службы переднего плана.
  • Если приложение ориентировано на Android 14 (уровень API 34) или выше, оно должно соответствовать всем предварительным требованиям для своего типа службы переднего плана. Эти предварительные требования подробно описаны в документации по типам служб переднего плана . В частности, обратите внимание на следующие требования:
    • Для некоторых типов служб переднего плана требуются определенные разрешения во время выполнения. Например, служба удаленного обмена сообщениями переднего плана должна иметь разрешение FOREGROUND_SERVICE_REMOTE_MESSAGING .
  • В ряде случаев существуют дополнительные ограничения на разрешения, необходимые для работы некоторых типов служб переднего плана во время их использования. Эти разрешения предоставляются приложению только тогда, когда оно находится на переднем плане ( с несколькими исключениями ). Это означает, что даже если ваше приложение запросило и получило одно из этих разрешений, если приложение попытается запустить службу переднего плана, находясь в фоновом режиме, система выдаст исключение SecurityException даже если у приложения есть исключение, позволяющее запускать службу переднего плана из фонового режима. Для получения дополнительной информации см. раздел «Ограничения на запуск служб переднего плана, требующих разрешений во время их использования» .
    • Вы можете получить исключение SecurityException если запросили необходимые разрешения, но запустили службу переднего плана до подтверждения предоставления требуемых разрешений.

Исправить :

Перед запуском фоновой службы запросите все необходимые разрешения для нее и убедитесь, что выполнены все остальные предварительные условия выполнения.