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

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

기기가 잠자기 모드일 때는 배터리를 많이 사용하는 특정 리소스에 관한 앱 액세스가 유지보수 기간까지 지연됩니다. 구체적인 제한사항은 전력 관리 제한사항에 나와 있습니다.

잠자기 및 앱 대기는 구체적으로 API 수준 23을 타겟팅하는지 여부와 상관없이 Android 6.0 이상에서 실행되는 모든 앱의 동작을 관리합니다. 사용자에게 최상의 환경을 제공할 수 있도록 잠자기 및 앱 대기 모드에서 앱을 테스트하고 필요에 따라 코드를 조정하세요. 다음 섹션에서는 세부정보를 제공합니다.

잠자기 이해

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

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

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

유지보수 기간이 끝나면 시스템이 다시 잠자기 모드로 전환되어 네트워크 액세스가 정지되고 작업, 동기화, 알람이 지연됩니다. 시간이 지날수록 시스템은 유지관리 기간의 빈도를 낮춥니다. 따라서 기기가 충전 중이 아닐 때 활동이 없는 경우 배터리 소모를 줄이는 데 도움이 됩니다.

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

잠자기 모드 제한사항

시스템은 잠자기 모드에서 다음과 같은 제한을 앱에 적용합니다.

  • 네트워크 액세스를 정지합니다.
  • wake lock을 무시합니다.
  • setExact()setWindow()를 포함한 표준 AlarmManager 알람을 다음 유지보수 기간으로 연기합니다.
  • Wi-Fi 검색을 수행하지 않습니다.
  • 동기화 어댑터를 실행할 수 없습니다.
  • JobScheduler가 실행되지 않도록 합니다.

잠자기 모드 체크리스트

잠자기 모드에 맞게 앱 조정

잠자기는 앱에서 제공하는 기능과 앱에서 사용하는 서비스에 따라 앱에 서로 다른 영향을 줄 수 있습니다. 많은 앱은 수정 없이 잠자기 주기에서 정상적으로 작동합니다. 경우에 따라 앱에서 네트워크, 알람, 작업, 동기화를 관리하는 방법을 최적화해야 합니다. 앱은 각 유지보수 기간 동안 활동을 효율적으로 관리할 수 있어야 합니다.

알람을 예약하는 데 도움이 되도록 두 가지 AlarmManager 메서드(setAndAllowWhileIdle()setExactAndAllowWhileIdle())를 사용할 수 있습니다. 이러한 메서드를 사용하면 기기가 잠자기 모드일 때에도 알람이 실행되도록 설정할 수 있습니다.

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

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

앱 대기 이해하기

앱 대기는 사용자가 활발하게 사용하지 않는 경우 시스템에서 앱이 유휴 상태라고 판단할 수 있게 해줍니다. 시스템은 사용자가 일정 시간 동안 앱을 터치하지 않고 다음 조건 중 어느 것도 적용되지 않으면 이 결정을 내립니다.

  • 사용자가 명시적으로 앱을 실행합니다.
  • 앱에 현재 포그라운드에 있는 프로세스(활동 또는 포그라운드 서비스 중 하나)가 있거나 다른 활동 또는 포그라운드 서비스에서 사용 중입니다.
  • 사용자가 잠금 화면이나 알림 목록에서 볼 수 있는 알림을 앱에서 생성합니다.

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

기기가 유휴 상태일 때 FCM을 사용하여 앱과 상호작용

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

FCM은 잠자기 및 앱 대기 유휴 모드 사용에 최적화되어 있습니다. FCM 높은 우선순위 메시지를 사용하면 앱의 절전 모드를 해제하여 사용자의 참여를 유도할 수 있습니다. 잠자기 또는 앱 대기 모드에서는 시스템이 메시지를 전송하고 앱이 네트워크 서비스 및 부분 wake lock에 일시적으로 액세스할 수 있도록 한 다음 기기 또는 앱을 유휴 상태로 되돌립니다. 시간에 민감한 사용자에게 표시되는 알림의 경우 우선순위가 높은 메시지를 사용하여 잠자기 모드에서 전송을 사용 설정해 보세요. 우선순위가 높은 메시지로 인해 알림이 전송될 수 있습니다. 자세한 내용은 우선순위가 높은 메시지에 관한 FCM 가이드를 참고하세요.

백그라운드에서 앱 콘텐츠를 최신 상태로 유지하거나 데이터 동기화를 시작하는 등 알림이 발생하지 않는 메시지의 경우 보통 우선순위의 FCM 메시지를 사용합니다. 기기가 잠자기 상태가 아니면 보통 우선순위 메시지가 즉시 전송됩니다. 기기가 잠자기 모드인 경우 주기적인 잠자기 유지보수 기간 동안 또는 사용자가 기기의 절전 모드를 해제하는 즉시 전송됩니다.

일반적으로 앱에 다운스트림 메시징이 필요한 경우 FCM을 사용합니다. 앱에서 이미 FCM을 사용하는 경우 사용자에게 표시되는 알림을 받는 메시지에만 우선순위가 높은 메시지를 사용해야 합니다.

기타 사용 사례 지원

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

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

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

앱은 isIgnoringBatteryOptimizations()를 호출하여 앱이 현재 예외 목록에 있는지 확인할 수 있습니다.

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

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

잠자기로 앱 테스트

다음을 실행하여 잠자기 모드를 테스트할 수 있습니다.

  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. 활성화되면 앱의 동작을 관찰합니다. 앱이 대기 모드에서 정상적으로 복구되는지 확인해야 합니다. 특히 앱의 알림과 백그라운드 작업이 예상대로 작동하는지 확인합니다.

허용되는 예외 사용 사례

다음 표에서는 몇 가지 사용 사례와 이러한 상황에서 앱이 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 인텐트 작업을 사용해도 되는지를 보여줍니다. 일반적으로 잠자기 또는 앱 대기 모드로 인해 앱의 핵심 기능이 중단되거나 앱에서 FCM 높은 우선순위 메시지를 사용할 수 없는 기술적인 이유가 없다면 일반적으로 앱은 이러한 예외를 충족하지 않습니다.

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

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