포그라운드 서비스 문제 해결

이 페이지에서는 포그라운드 서비스가 실패할 수 있는 몇 가지 일반적인 이유를 설명하고 문제를 일으키는 원인을 파악하는 데 도움이 됩니다.

이 문서에서는 다음 문제를 설명합니다.

문제 해결 전 준비사항

포그라운드 서비스의 최근 변경사항 확인

포그라운드 서비스를 부적절하게 사용하면 기기 성능과 배터리 수명에 부정적인 영향을 미칠 수 있습니다. 이러한 이유로 Android 플랫폼 출시에서는 이러한 부작용을 제한하기 위해 포그라운드 서비스 동작을 변경하는 경우가 많습니다.

포그라운드 서비스에 문제가 있는 경우 포그라운드 서비스 변경사항 문서를 확인하고 문제를 설명할 수 있는 최근 변경사항이 있는지 확인해야 합니다. 다음과 같은 경우에는 특히 변경사항을 확인하는 것이 중요합니다.

  • 이전에 작동했던 포그라운드 서비스 코드가 실패함
  • 새 플랫폼 출시에서 테스트를 시작했거나 앱에서 타겟팅하는 API 수준을 변경했습니다.

또한 플랫폼의 개발자 프리뷰에서 기기를 테스트하는 경우 최신 버전의 개발자 프리뷰 문서를 확인하세요.

애플리케이션 응답 없음 (ANR) 오류

특정 상황에서는 앱이 포그라운드 서비스를 종료해야 합니다. 앱이 서비스를 중지하지 않으면 시스템에서 서비스를 중지하고 애플리케이션 응답 없음 (ANR) 오류를 트리거합니다.

짧은 서비스가 너무 오래 실행되어 ANR이 발생함

짧은 서비스 유형을 사용하는 포그라운드 서비스는 약 3분 이내에 빠르게 완료되어야 합니다. 시간이 다 지나면 시스템은 서비스의 Service.onTimeout(int,int) 메서드를 호출합니다. 서비스는 stopSelf()를 호출할 수 있는 몇 초의 시간이 있습니다. 서비스가 자동으로 중지되지 않으면 시스템에서 애플리케이션 응답 없음 오류를 트리거합니다.

진단:

포그라운드 서비스가 자체적으로 중지되지 않아 ANR이 발생한 경우 시스템은 내부 예외를 발생시킵니다. Logcat을 확인하여 이 문제가 맞는지 확인할 수 있습니다. 이 경우 로그에 다음 메시지가 포함됩니다.

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()를 호출할 수 있는 몇 초의 시간이 있습니다. 서비스가 자체적으로 중지되지 않으면 시스템에서 내부 예외를 생성하여 앱이 비정상 종료됩니다.

진단:

제한 시간 초과가 원인인 경우 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()를 호출하여 포그라운드 서비스로 승격할 수 있는 몇 초의 시간이 있습니다. 서비스가 이를 실행하지 않으면 시스템에서 ANR 오류를 트리거합니다.

진단:

포그라운드 서비스가 제때 시작되지 않으면 앱이 비정상 종료되어 사용자에게 앱이 중지됨 대화상자가 표시됩니다. 이 경우 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 버전을 변경한 경우 포그라운드 서비스 변경사항 문서를 확인하고 앱이 여전히 허용되는 예외 중 하나를 충족하는지 확인합니다.

해결 방법:

앱이 백그라운드에 있는 동안 포그라운드 서비스를 실행할 필요가 없도록 앱의 워크플로를 변경하거나 앱이 예외 중 하나를 충족하는지 확인합니다.

LiveData와 같은 수명 주기 구성요소를 사용하여 앱의 수명 주기를 관리하면 의도치 않게 백그라운드에서 포그라운드 서비스를 실행하려고 하지 않습니다.

SecurityException

오류:

시스템에서 SecurityException을 발생시킵니다.

원인:

앱이 필요한 권한 없이 포그라운드 서비스를 실행하려고 시도했습니다.

  • 앱이 Android 9 (API 수준 28) 이상을 타겟팅하는 경우 포그라운드 서비스를 실행하려면 FOREGROUND_SERVICE 권한이 있어야 합니다.
  • 앱이 Android 14 (API 수준 34) 이상을 타겟팅하는 경우 포그라운드 서비스 유형의 모든 기본 요건을 충족해야 합니다. 이러한 기본 요건은 포그라운드 서비스 유형 문서에 자세히 설명되어 있습니다. 특히 다음 요구사항에 유의하세요.
    • 일부 포그라운드 서비스 유형에는 특정 런타임 권한이 필요합니다. 예를 들어 원격 메시지 포그라운드 서비스에는 FOREGROUND_SERVICE_REMOTE_MESSAGING 권한이 있어야 합니다.
  • 경우에 따라 일부 포그라운드 서비스 유형에 필요한 권한에 사용 중 제한사항이 추가로 적용됩니다. 이러한 권한은 앱이 포그라운드에 있는 동안에만 앱에 부여됩니다 (일부 특정 예외 제외). 즉, 앱이 이러한 권한 중 하나를 요청하고 부여받았다고 하더라도 앱이 백그라운드에 있는 동안 포그라운드 서비스를 실행하려고 하면 시스템은 앱에 백그라운드에서 포그라운드 서비스를 시작할 수 있는 예외가 있더라도 SecurityException을 발생시킵니다. 자세한 내용은 사용 중 권한이 필요한 포그라운드 서비스 시작에 관한 제한사항을 참고하세요.
    • 필요한 권한을 요청했지만 필요한 권한이 부여되었는지 확인하기 전에 포그라운드 서비스를 시작하면 SecurityException이 발생할 수 있습니다.

해결 방법:

포그라운드 서비스를 실행하기 전에 적절한 포그라운드 서비스 권한을 모두 요청하고 다른 모든 런타임 기본 요건을 충족했는지 확인합니다.