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

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

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

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

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

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

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

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

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

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

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

Короткие рейсы слишком длинные, что приводит к ANR

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

Диагностика :

Если ошибка 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() в течение нескольких секунд.

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 , если вы запросили необходимые разрешения, но запустили службу переднего плана до подтверждения предоставления требуемых разрешений.

Исправить :

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