백그라운드 실행 제한

앱이 백그라운드에서 실행될 때마다 RAM과 같은 기기의 제한된 리소스 중 일부를 사용합니다. 특히 사용자가 게임을 하거나 동영상을 시청하는 등 리소스 집약적인 앱을 사용하는 경우 사용자 환경이 저하될 수 있습니다. Android 8.0(API 수준 26)은 사용자 환경을 개선하기 위해 앱이 백그라운드에서 실행되는 동안 할 수 있는 작업에 제한을 적용합니다. 이 문서에서는 운영체제의 변경사항과 새 제한사항에 맞게 앱을 업데이트하는 방법을 설명합니다.

개요

많은 수의 Android 앱과 서비스를 동시에 실행할 수 있습니다. 예를 들어 사용자가 한 창에서 게임을 플레이하는 동안 다른 창에서 웹을 탐색하고 서드 파티 앱을 사용하여 음악을 재생할 수 있습니다. 한 번에 실행되는 앱이 많을수록 시스템에 더 많은 부하가 발생합니다. 백그라운드에서 추가 앱이나 서비스가 실행되면 시스템에 추가 부하가 발생하여 사용자 환경이 저하될 수 있습니다. 예를 들어 음악 앱이 갑자기 종료될 수 있습니다.

이러한 문제가 발생할 가능성을 줄이기 위해 Android 8.0에서는 사용자가 앱과 직접 상호작용하지 않는 동안 앱이 할 수 있는 작업을 제한합니다. 앱은 두 가지 방식으로 제한됩니다.

  • 백그라운드 서비스 제한: 앱이 유휴 상태일 때 백그라운드 서비스 사용에는 제한이 있습니다. 이는 사용자에게 더 눈에 띄는 포그라운드 서비스에는 적용되지 않습니다.

  • 브로드캐스트 제한사항: 제한적인 예외를 제외하고 앱은 매니페스트를 사용하여 암시적 브로드캐스트를 등록할 수 없습니다. 런타임에 이러한 브로드캐스트를 등록할 수 있으며 매니페스트를 사용하여 명시적 브로드캐스트와 앱을 구체적으로 타겟팅하는 브로드캐스트를 등록할 수 있습니다.

대부분의 경우 앱은 JobScheduler 작업을 사용하여 이러한 제한을 해결할 수 있습니다. 이 접근 방식을 사용하면 앱이 활발하게 실행되지 않을 때 작업을 실행하도록 앱을 정렬할 수 있지만 시스템은 사용자 환경에 영향을 미치지 않는 방식으로 이러한 작업을 예약할 수 있습니다. Android 8.0에서는 JobScheduler를 개선하여 서비스와 broadcast receiver를 예약된 작업으로 더 쉽게 대체할 수 있도록 했습니다. 자세한 내용은 JobScheduler 개선사항을 참고하세요.

백그라운드 서비스 제한사항

백그라운드에서 실행되는 서비스는 기기 리소스를 소비하여 사용자 환경이 저하될 수 있습니다. 이 문제를 완화하기 위해 시스템은 서비스에 여러 가지 제한사항을 적용합니다.

시스템은 포그라운드 앱과 백그라운드 앱을 구분합니다. 서비스 제한을 목적으로 하는 백그라운드의 정의는 메모리 관리에서 사용하는 정의와 다릅니다. 앱이 메모리 관리와 관련하여 백그라운드에 있을 수 있지만 서비스 시작 기능과 관련하여 포그라운드에 있을 수 있습니다. 다음 조건 중 하나라도 참일 경우 앱이 포그라운드에 있는 것으로 간주합니다.

  • 액티비티가 시작되든 일시 중지되든 상관없이, 보이는 액티비티가 있는 경우
  • 포그라운드 서비스가 있는 경우
  • 앱의 서비스 중 하나에 바인딩되거나 앱의 콘텐츠 제공자 중 하나를 사용하여 앱에 또 다른 포그라운드 앱이 연결된 경우. 예를 들어 다른 앱이 다음에 바인딩하면 앱이 포그라운드에 있는 것입니다.
    • IME
    • 배경화면 서비스
    • 알림 리스너
    • 음성 또는 텍스트 서비스

위의 조건 중 어느 것에도 해당하지 않는 경우 앱이 백그라운드에 있는 것으로 간주됩니다.

앱이 포그라운드에 있는 동안 포그라운드 서비스와 백그라운드 서비스를 모두 자유롭게 만들고 실행할 수 있습니다. 앱이 백그라운드로 전환되면 앱에서 서비스를 만들고 사용할 수 있는 몇 분의 시간이 주어집니다. 이 기간이 끝나면 앱이 유휴 상태로 간주됩니다. 이때 시스템은 앱이 서비스의 Service.stopSelf() 메서드를 호출한 것처럼 앱의 백그라운드 서비스를 중지합니다.

특정 상황에서 백그라운드 앱이 몇 분 동안 임시 허용 목록에 추가됩니다. 앱이 허용 목록에 있는 동안에는 제한 없이 서비스를 실행할 수 있으며 백그라운드 서비스가 실행되도록 허용됩니다. 앱이 사용자에게 표시되는 작업을 처리하면 허용 목록에 추가됩니다(예:

대부분의 경우 앱은 백그라운드 서비스를 JobScheduler 작업으로 대체할 수 있습니다. 예를 들어 CoolPhotoApp은 앱이 포그라운드에서 실행되지 않더라도 사용자가 친구로부터 공유된 사진을 받았는지 확인해야 합니다. 이전에는 앱의 클라우드 스토리지를 확인하는 백그라운드 서비스를 사용했습니다. Android 8.0 (API 수준 26)으로 이전하려면 개발자가 백그라운드 서비스를 정기적으로 실행되고 서버를 쿼리한 후 종료되는 예약된 작업으로 대체합니다.

Android 8.0 이전에는 포그라운드 서비스를 만드는 일반적인 방법은 백그라운드 서비스를 만든 다음 해당 서비스를 포그라운드로 승격하는 것이었습니다. Android 8.0에서는 문제가 있습니다. 시스템에서 백그라운드 앱이 백그라운드 서비스를 만들도록 허용하지 않습니다. 따라서 Android 8.0에서는 포그라운드에서 새 서비스를 시작하는 새로운 메서드 startForegroundService()를 도입합니다. 시스템이 서비스를 만든 후 앱은 5초 이내에 서비스의 [startForeground()](/reference/android/app/Service#startForeground(int, android.app.Notification) 메서드를 호출하여 새 서비스의 사용자에게 표시되는 알림을 표시해야 합니다. 앱이 시간 제한 내에 startForeground()를 호출하지 않으면 시스템은 서비스를 중지하고 앱을 ANR으로 선언합니다.

브로드캐스트 제한사항

앱이 브로드캐스트를 수신하도록 등록하면 브로드캐스트가 전송될 때마다 앱의 수신자가 리소스를 사용합니다. 이렇게 하면 시스템 이벤트를 기반으로 브로드캐스트를 수신하도록 등록하는 앱이 너무 많아질 경우 문제가 발생할 수 있습니다. 브로드캐스트를 트리거하는 시스템 이벤트로 인해 이러한 모든 앱이 리소스를 빠르게 소비하여 사용자 환경이 저하될 수 있습니다. 이 문제를 완화하기 위해 Android 7.0 (API 수준 24)에서는 백그라운드 최적화에 설명된 대로 브로드캐스트에 제한을 적용했습니다. Android 8.0(API 레벨 26)은 이러한 제한을 더욱 강화했습니다.

  • Android 8.0 이상을 타겟팅하는 앱은 브로드캐스트가 해당 앱으로 구체적으로 제한되지 않는 한 더 이상 매니페스트에서 암시적 브로드캐스트의 broadcast receiver를 등록할 수 없습니다. 암시적 브로드캐스트는 앱 내 특정 구성요소를 타겟팅하지 않는 브로드캐스트입니다. 예를 들어 ACTION_PACKAGE_REPLACED는 모든 앱에 등록된 모든 리스너에게 전송되어 기기의 일부 패키지가 교체되었음을 알립니다. 브로드캐스트가 암시적이므로 Android 8.0 이상을 타겟팅하는 앱의 매니페스트 등록 수신기에는 전송되지 않습니다. ACTION_MY_PACKAGE_REPLACED도 암시적 브로드캐스트이지만 패키지가 교체된 앱에만 전송되므로 매니페스트 등록 수신기에 전송됩니다.
  • 앱은 자체 매니페스트에 있는 명시적 브로드캐스트에 계속해서 등록할 수 있습니다.
  • 앱은 런타임에 Context.registerReceiver()를 사용하여 암시적 또는 명시적 브로드캐스트의 수신기를 등록할 수 있습니다.
  • 서명 권한이 필요한 브로드캐스트는 이 제한사항에서 예외입니다. 이러한 브로드캐스트는 기기의 모든 앱이 아닌 동일한 인증서로 서명된 앱으로만 전송되기 때문입니다.

이전에 암시적 브로드캐스트를 등록한 앱은 대부분 JobScheduler 작업을 사용하여 유사한 기능을 얻을 수 있습니다. 예를 들어 소셜 사진 앱은 때때로 데이터를 정리해야 할 수 있으며, 기기가 충전기에 연결되어 있을 때 이를 실행하는 것이 좋습니다. 이전에는 앱이 매니페스트에 ACTION_POWER_CONNECTED의 수신기를 등록했습니다. 앱이 이 브로드캐스트를 수신하면 정리가 필요한지 확인했습니다. Android 8.0 이상으로 이전하기 위해 앱은 매니페스트에서 해당 수신기를 삭제합니다. 대신 앱은 기기가 유휴 상태이고 충전 중일 때 실행되는 정리 작업을 예약합니다.

이전 가이드

기본적으로 이러한 변경사항은 Android 8.0 (API 수준 26) 이상을 타겟팅하는 앱에만 영향을 미칩니다. 그러나 앱이 26보다 낮은 API 수준을 타겟팅하더라도 사용자는 설정 화면에서 모든 앱에 이러한 제한을 사용 설정할 수 있습니다. 새로운 제한사항을 준수하도록 앱을 업데이트해야 할 수도 있습니다.

앱에서 서비스가 어떻게 사용되는지 확인하세요. 앱이 앱이 유휴 상태일 때 백그라운드에서 실행되는 서비스를 사용하는 경우 이를 대체해야 합니다. 가능한 해결책은 다음과 같습니다.

  • 앱이 백그라운드에 있는 동안 앱에서 포그라운드 서비스를 만들어야 한다면 startService() 대신 startForegroundService() 메서드를 사용하세요.
  • 서비스가 사용자에게 보이는 경우, 이 서비스를 포그라운드 서비스로 만듭니다. 예를 들어 오디오를 재생하는 서비스는 항상 포그라운드 서비스여야 합니다. startService() 대신 startForegroundService() 메서드를 사용하여 서비스를 만듭니다.
  • 예약된 작업으로 서비스의 기능을 복제하는 방법을 찾습니다. 서비스가 사용자에게 즉시 눈에 띄는 작업을 실행하지 않는 경우 일반적으로 예약된 작업을 대신 사용할 수 있습니다.
  • 백그라운드에서 폴링하는 대신 FCM을 사용하여 네트워크 이벤트가 발생할 때 애플리케이션을 선택적으로 깨웁니다.
  • 애플리케이션이 자연스럽게 포그라운드가 될 때까지 백그라운드 작업을 연기합니다.

앱 매니페스트에 정의된 broadcast receiver를 검토합니다. 매니페스트에서 영향을 받는 암시적 브로드캐스트의 수신기를 선언하는 경우 이를 대체해야 합니다. 가능한 해결책은 다음과 같습니다.

  • 매니페스트에서 수신자를 선언하는 대신 Context.registerReceiver()를 호출하여 런타임에 수신기를 만듭니다.
  • 예약된 작업을 사용하여 암시적 브로드캐스트를 트리거했을 조건을 확인합니다.