잠자기 및 앱 대기 모드에 맞게 최적화

Android는 Android 6.0(API 레벨 23)부터 두 가지 절전 기능을 도입했습니다. 사용자는 기기가 전원 공급 장치에 연결되어 있지 않을 때 앱이 작동하는 방식을 관리하여 배터리 수명을 연장할 수 있습니다. 잠자기 모드는 기기를 오랫동안 사용하지 않는 경우 앱의 백그라운드 CPU 및 네트워크 활동을 지연시켜 배터리 소모를 줄입니다. 앱 대기 모드는 최근 사용자와 상호작용이 없는 앱의 백그라운드 네트워크 활동을 지연시킵니다.

기기가 잠자기 모드이면 배터리 소모가 큰 특정 리소스에 관한 앱 액세스가 유지보수 기간까지 지연됩니다. 자세한 제한사항은 전원 관리 제한사항에 나와 있습니다.

잠자기 및 앱 대기 모드에서는 앱이 API 레벨 23을 타겟팅하는지 여부와 상관없이 Android 6.0 이상에서 실행되는 모든 앱의 동작을 관리합니다. 사용자에게 최고의 환경을 제공할 수 있도록 잠자기 및 앱 대기 모드에서 앱을 테스트하여 필요에 따라 코드를 조정해야 합니다. 자세한 내용은 아래 섹션에서 설명합니다.

잠자기 모드 이해

사용자가 플러그를 뽑고 화면이 꺼진 채로 기기를 일정 기간 정지 상태로 두면 기기는 잠자기 모드를 시작합니다. 잠자기 모드에서는 시스템이 네트워크 및 CPU를 많이 사용하는 서비스에 대한 앱의 액세스를 제한하여 배터리를 절약하려고 합니다. 또한, 앱이 네트워크에 액세스하지 못하도록 하고 작업, 동기화 및 표준 알람을 지연시킵니다.

시스템은 앱에서 지연된 활동을 완료할 수 있도록 주기적으로 잠깐 동안 잠자기 모드를 종료합니다. 이러한 유지보수 기간 동안 시스템은 대기 중인 동기화, 작업 및 알람을 모두 실행하고 앱이 네트워크에 액세스할 수 있도록 허용합니다.

그림 1. 잠자기 모드에서는 앱이 네트워크를 사용하고 대기 중인 활동을 처리할 수 있는 유지보수 기간을 반복적으로 제공합니다.

각 유지보수 기간이 끝나면 시스템은 다시 잠자기 모드를 시작하여 네트워크 액세스는 정지되고 작업, 동기화 및 알람은 지연됩니다. 시간이 지날수록 시스템은 유지보수 기간의 횟수를 줄입니다. 그 이유는 기기가 충전기에 연결되어 있지 않은 상태에서 비활성 기간이 길어지는 경우 배터리 소모를 줄일 수 있기 때문입니다.

사용자가 기기를 움직이거나 화면을 켜거나 충전기를 연결하여 기기 절전 모드를 해제하면 시스템은 잠자기 모드를 종료하고 모든 앱은 정상적인 활동으로 돌아갑니다.

잠자기 모드 제한사항

앱이 잠자기 모드 상태에 있는 동안 다음과 같은 제한사항이 적용됩니다.

  • 네트워크 액세스가 정지됩니다.
  • 시스템에서 wake lock을 무시합니다.
  • 표준 AlarmManager 알람(setExact()setWindow() 포함)이 다음 유지보수 기간까지 지연됩니다.
    • 잠자기 모드에서도 실행되는 알람을 설정해야 하는 경우 setAndAllowWhileIdle() 또는 setExactAndAllowWhileIdle()를 사용합니다.
    • setAlarmClock()로 설정된 알람은 정상적으로 실행됩니다. 시스템에서 해당 알람이 실행되기 직전에 잠자기 모드를 종료합니다.
  • 시스템에서 Wi-Fi 검색을 수행하지 않습니다.
  • 시스템에서 동기화 어댑터 실행을 허용하지 않습니다.
  • 시스템에서 JobScheduler 실행을 허용하지 않습니다.

잠자기 모드 체크리스트

잠자기 모드에 맞게 앱 조정

앱에서 제공하는 기능과 사용하는 서비스에 따라 잠자기 모드가 앱에 미치는 영향이 다를 수 있습니다. 대부분의 앱은 수정하지 않아도 잠자기 주기에서 정상적으로 작동합니다. 하지만 앱에서 네트워크, 알람, 작업 및 동기화를 관리하는 방법을 최적화해야 하는 경우도 있습니다. 앱은 각 유지보수 기간 동안 효율적으로 활동을 관리할 수 있어야 합니다.

잠자기 모드는 특히 AlarmManager 알람 및 타이머가 관리하는 활동에 영향을 줄 가능성이 높습니다. 시스템이 잠자기 모드인 경우 Android 5.1(API 레벨 22) 이하에서는 알람이 실행되지 않기 때문입니다.

알람 예약을 지원하기 위해 Android 6.0(API 레벨 23)에서는 두 가지 새로운 AlarmManager 메서드 setAndAllowWhileIdle()setExactAndAllowWhileIdle()가 도입되었습니다. 이러한 메서드를 사용하면 기기가 잠자기 모드인 경우에도 알람이 실행되도록 설정할 수 있습니다.

참고: setAndAllowWhileIdle()setExactAndAllowWhileIdle() 모두 앱당 9분마다 한 번만 알람을 실행할 수 있습니다.

잠자기 모드에서 네트워크 액세스가 제한되는 상황도 앱에 영향을 미칠 수 있습니다. 특히, 앱이 Tickle 또는 알림과 같은 실시간 메시지를 사용하는 경우에 그렇습니다. 메시지를 수신하기 위해 앱이 네트워크에 영구적으로 연결되어 있어야 하는 경우 가능하면 FCM(Firebase 클라우드 메시징)을 사용해야 합니다.

앱이 잠자기 모드에서 예상대로 작동하는지 확인하려면 adb 명령어를 사용하여 시스템에서 강제로 잠자기 모드를 시작하고 종료하면서 앱 작동을 관찰합니다. 자세한 내용은 잠자기 및 앱 대기 모드로 테스트를 참조하세요.

앱 대기 모드 이해

앱 대기 모드에서는 사용자가 앱을 활발하게 사용하지 않으면 시스템에서 앱이 유휴 상태라고 판단합니다. 시스템에서 이렇게 판단하려면 사용자가 일정 기간 앱을 터치하지 않아야 하며 다음 중 어느 조건에도 해당하지 않아야 합니다.

  • 사용자가 명시적으로 앱을 실행합니다.
  • 앱 프로세스가 현재 포그라운드에 있습니다(활동 또는 포그라운드 서비스로 있거나 다른 활동 또는 포그라운드 서비스에 사용되고 있음).

    참고: 포그라운드 서비스는 사용자가 시스템에서 즉시 또는 중단없이 실행되기를 기대하는 작업에만 사용해야 합니다. 이러한 예로는 소셜 미디어로 사진을 업로드하거나 음악 플레이어 앱이 포그라운드에 없어도 음악을 재생하는 경우를 들 수 있습니다. 단지 시스템에서 앱이 유휴 상태라고 판단하지 않도록 하기 위해 포그라운드 서비스를 시작해서는 안 됩니다.

  • 사용자가 잠금 화면이나 알림 목록에서 볼 수 있는 알림을 앱에서 생성합니다.
  • 앱이 활성 기기 관리 앱(예: 기기 정책 컨트롤러)입니다. 이러한 앱은 일반적으로 백그라운드에서 실행되지만 기기 관리 앱은 언제든 서버에서 정책을 수신할 수 있게 유지되어야 하므로 앱 대기 모드를 시작하지 않습니다.

사용자가 기기를 전원 공급 장치에 연결하면 시스템은 앱을 대기 모드에서 해제하므로 앱이 자유롭게 네트워크에 액세스하며 대기 중인 작업 및 동기화를 실행할 수 있습니다. 기기가 오랜 기간 동안 유휴 상태인 경우에는 시스템에서 유휴 상태인 앱이 하루에 한 번 정도 네트워크에 액세스하도록 허용합니다.

기기가 유휴 상태일 때 앱과의 상호작용에 FCM 사용

FCM(Firebase 클라우드 메시징)은 클라우드에서 기기로 푸시하는 서비스로, 이 서비스를 이용하면 Android 기기에서 백엔드 서비스와 앱 간에 실시간 다운스트림 메시징을 지원할 수 있습니다. FCM은 클라우드와의 영구적 단일 연결을 제공하므로 실시간 메시징이 필요한 모든 앱에서 이 연결을 공유할 수 있습니다. 연결을 공유하면 여러 앱이 고유한 별도의 영구적 연결을 유지보수하느라 배터리를 빠르게 소모할 일이 없어 배터리 소모를 최적화할 수 있습니다. 이러한 이유로 앱이 백엔드 서비스와 메시징을 통합해야 하는 경우 Google은 고유한 영구적 네트워크 연결을 유지보수하지 말고 가능한 한 FCM을 사용할 것을 권장합니다.

FCM은 높은 우선순위 FCM 메시지를 통해 잠자기 및 앱 대기 유휴 모드 사용에 맞게 최적화됩니다. FCM 높은 우선순위 메시지를 사용하면 사용자 기기가 잠자기 모드이거나 앱이 앱 대기 모드인 경우에도 안정적으로 앱의 절전 모드를 해제하여 네트워크에 액세스할 수 있습니다. 잠자기 또는 앱 대기 모드에서는 시스템이 메시지를 제공하여 앱이 네트워크 서비스 및 부분 wake lock에 일시적으로 액세스할 수 있도록 한 다음, 기기 또는 앱을 유휴 상태로 되돌립니다.

이 외에는 높은 우선순위 FCM 메시지가 잠자기 모드에 영향을 미치지 않으며 다른 앱의 상태에도 영향을 미치지 않습니다. 다시 말해, 높은 우선순위 FCM 메시지를 사용하면 앱이 효율적으로 커뮤니케이션하는 동시에 배터리가 시스템 및 기기에 미치는 영향을 최소화할 수 있습니다.

일반적으로 앱에 다운스트림 메시징이 필요한 경우 FCM을 사용하는 것이 좋습니다. 서버 및 클라이언트에서 이미 FCM을 사용하고 있는 경우 서비스에서 중요한 메시지에 높은 우선순위 메시지를 사용하도록 하세요. 이렇게 하면 기기가 잠자기 모드인 경우에도 안정적으로 앱의 절전 모드를 해제할 수 있습니다.

기타 사용 사례 지원

거의 모든 앱은 네트워크 연결, 알람, 작업 및 동기화를 제대로 관리하고 FCM 높은 우선순위 메시지를 사용하여 잠자기 모드를 지원할 수 있습니다. 하지만 일부 사용 사례에서는 이것만으로는 부족합니다. 부족한 경우 시스템은 잠자기 및 앱 대기 모드 최적화에서 부분적으로 제외할 앱에 관한 허용 목록을 구성할 수 있도록 지원합니다.

허용 목록에 추가된 앱은 잠자기 및 앱 대기 모드 중 네트워크를 사용하고 부분 wake lock을 보유할 수 있습니다. 하지만 허용 목록에 추가된 앱에도 다른 앱과 마찬가지로 다른 제한사항은 여전히 적용됩니다. 예를 들어 API 레벨 23 이하에서는 허용 목록에 추가된 앱의 작업 및 동기화가 지연되며 일반 AlarmManager 알람이 실행되지 않습니다. isIgnoringBatteryOptimizations()를 호출하면 앱이 현재 제외 허용 목록에 포함되어 있는지 확인할 수 있습니다.

사용자는 설정 > 배터리 > 배터리 최적화에서 허용 목록을 수동으로 구성할 수 있습니다. 앱에서 사용자에게 허용 목록 추가를 요청하는 방법을 시스템이 제공할 수도 있습니다.

  • 앱은 ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS 인텐트를 실행하여 사용자가 앱을 추가할 수 있는 배터리 최적화로 바로 이동하게 할 수 있습니다.
  • REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 권한이 있는 앱은 시스템 대화상자를 트리거하여 사용자가 설정으로 이동하지 않고도 직접 허용 목록에 앱을 추가하도록 할 수 있습니다. 앱은 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 인텐트를 실행하여 대화상자를 트리거합니다.
  • 필요한 경우, 사용자는 허용 목록에서 수동으로 앱을 제거할 수 있습니다.

허용 목록에 앱을 추가하도록 사용자에게 요청하기 전에 앱이 허용 목록에 추가할 수 있는 사용 사례에 해당하는지 확인하세요.

참고: Google Play 정책에서는 앱의 핵심 기능에 악영향을 미치는 경우가 아니면 앱이 Android 6.0 이상의 전원 관리 기능(잠자기 및 앱 대기 모드)에서 직접 제외 요청을 하는 것을 금지하고 있습니다.

잠자기 및 앱 대기 모드로 테스트

사용자에게 최고의 환경을 제공할 수 있도록 잠자기 및 앱 대기 모드에서 철저하게 앱을 테스트해야 합니다.

잠자기 모드에서 앱 테스트

다음 단계에 따라 잠자기 모드를 테스트할 수 있습니다.

  1. Android 6.0(API 레벨 23) 이상의 시스템 이미지로 하드웨어 기기 또는 가상 기기를 구성합니다.
  2. 기기를 개발 머신에 연결하고 앱을 설치합니다.
  3. 앱을 실행시킨 다음 활성 상태로 그냥 둡니다.
  4. 다음 명령어를 실행하여 강제로 시스템을 유휴 모드로 지정합니다.
        $ adb shell dumpsys deviceidle force-idle
        
  5. 준비가 되면 다음 명령어를 실행하여 유휴 모드를 종료합니다.
        $ adb shell dumpsys deviceidle unforce
        
  6. 다음 명령어를 실행하여 기기를 다시 활성화합니다.
        $ adb shell dumpsys battery reset
          
  7. 기기를 다시 활성화한 후 앱의 동작을 관찰합니다. 기기가 잠자기 모드를 종료하면 앱이 원활하게 복구되는지 확인해야 합니다.

앱 대기 모드에서 앱 테스트

다음 단계에 따라 앱에서 앱 대기 모드를 테스트하세요.

  1. Android 6.0(API 레벨 23) 이상의 시스템 이미지로 하드웨어 기기 또는 가상 기기를 구성합니다.
  2. 기기를 개발 머신에 연결하고 앱을 설치합니다.
  3. 앱을 실행시킨 다음 활성 상태로 그냥 둡니다.
  4. 다음 명령어를 실행하여 앱에서 강제로 앱 대기 모드를 시작합니다.
    $ adb shell dumpsys battery unplug
        $ adb shell am set-inactive <packageName> true
  5. 다음 명령어를 사용하여 앱이 활성화되는 것을 시뮬레이션합니다.
    $ adb shell am set-inactive <packageName> false
        $ adb shell am get-inactive <packageName>
  6. 활성화되면 앱의 동작을 관찰합니다. 앱이 대기 모드에서 원활하게 복구되는지 확인해야 합니다. 특히, 앱의 알림과 백그라운드 작업이 계속 예상대로 작동하는지 확인해야 합니다.

허용 목록에 추가할 수 있는 사용 사례

아래 표에는 배터리 최적화 예외 허용 목록에 추가되어 있거나 추가를 요청할 수 있는 사용 사례가 강조표시되어 있습니다. 일반적으로, 잠자기 또는 앱 대기 모드로 인해 앱의 핵심 기능이 중단되거나 앱에서 FCM 높은 우선순위 메시지를 사용할 수 없는 기술적인 이유가 있는 경우가 아니면 앱을 허용 목록에 추가해서는 안 됩니다.

자세한 내용은 기타 사용 사례 지원을 참조하세요.

유형 사용 사례 FCM 사용 가능 여부 허용 목록에 추가 가능 여부 메모
채팅 또는 통화 앱 기기가 잠자기 모드이거나 앱이 앱 대기 모드일 때 사용자에게 실시간 메시지를 제공해야 합니다. 예, FCM을 사용합니다. 추가 불가능 FCM 높은 우선순위 메시지를 사용하여 앱의 절전 모드를 해제하고 네트워크에 액세스해야 합니다.
예, 하지만 FCM 높은 우선순위 메시지는 사용하지 않습니다.
채팅 또는 통화 앱, 기업용 VOIP 앱 아니요, 기술적인 이유로 다른 메시징 서비스를 사용하고 있거나 잠자기 및 앱 대기 모드로 인해 앱의 핵심 기능이 중단되기 때문에 FCM을 사용할 수 없습니다. 추가 가능
작업 자동화 앱 앱의 핵심 기능은 채팅, 음성 통화, 새로운 사진 관리 또는 위치 작업과 같이 자동화된 작업을 예약하는 것입니다. 해당하는 경우 사용합니다. 추가 가능
주변 기기 호환 앱 앱의 핵심 기능은 주변 기기에 인터넷 액세스를 제공하기 위해 주변 기기와의 영구적 연결을 유지하는 것입니다. 해당하는 경우 사용합니다. 추가 가능
앱은 주기적으로 동기화할 주변 기기 또는 무선 헤드폰과 같이 표준 블루투스 프로필을 통해 연결된 기기에만 연결해야 합니다. 해당하는 경우 사용합니다. 추가 불가능