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

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

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

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

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

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

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

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

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

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

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

Короткое обслуживание выполняется слишком долго, вызывая ANR

Службы переднего плана, использующие тип службы Short, должны завершиться быстро, примерно в течение трех минут. Когда время истекает, система вызывает метод службы 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() в течение нескольких секунд.

ForegroundServiceStartNotAllowedException

Ошибка :

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

Причина :

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

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

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

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

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

Исправить :

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

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

Исключение Безопасности

Ошибка :

Система выдает SecurityException .

Причина :

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

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

Исправить :

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