과도한 배터리 소모가 Android 사용자의 가장 큰 관심사임을 인식한 Google은 개발자가 더 효율적인 앱을 빌드할 수 있도록 지원하기 위해 상당한 조치를 취해 왔습니다. 2026년 3월 1일, Google Play 스토어에서 배터리 소모를 개선하기 위해 wake lock 기술 품질 처리를 출시하기 시작했습니다. 이 조치는 앞으로 몇 주에 걸쳐 영향을 받는 앱에 점진적으로 적용될 예정입니다. Android vitals에서 '과도한 부분 Wake Lock' 기준을 지속적으로 초과하는 앱은 스토어 등록정보에 경고가 표시되고 추천과 같은 검색 경로에서 제외되는 등 스토어 등록정보에 실질적인 영향을 받을 수 있습니다.
앱이 비정상적인 동작 기준을 초과하면 스토어 등록정보에 경고가 표시될 수 있습니다.
이 이니셔티브를 통해 배터리 효율성이 비정상 종료 및 ANR과 같은 안정성 측정항목과 함께 핵심 vitals 측정항목으로 격상되었습니다. '비정상적인 동작 기준'은 지난 28일 동안 5% 이상의 사용자 세션에서 화면이 꺼져 있는 동안 면제되지 않은 부분 wake lock을 평균 2시간 이상 보유하는 것으로 정의됩니다. 오디오 재생, 위치 액세스, 사용자 시작 데이터 전송과 같이 더 이상 최적화할 수 없는 명확한 사용자 혜택을 제공하는 시스템 유지 wake lock은 예외입니다. 불필요한 wake lock의 전체 정의는 Android vitals 문서에서 확인할 수 있습니다.
Android 생태계 전반에서 배터리 수명을 개선하기 위한 지속적인 노력의 일환으로 수천 개의 앱과 앱에서 부분 절전 모드를 사용하는 방식을 분석했습니다. 절전 모드 해제는 필요한 경우도 있지만, 더 효율적인 솔루션이 있는데도 앱이 비효율적으로 또는 불필요하게 절전 모드 해제를 유지하는 경우가 많습니다. 이 블로그에서는 과도한 절전 모드 해제가 발생하는 가장 일반적인 시나리오와 절전 모드 해제를 최적화하기 위한 권장사항을 살펴봅니다. 이미 WHOOP와 같은 파트너가 이러한 권장사항을 활용하여 백그라운드 동작을 최적화한 결과 측정 가능한 성공을 거두었습니다.
포그라운드 서비스 사용과 부분 절전 모드 사용의 차이점
백그라운드 실행 시 포그라운드 서비스와 부분 절전 모드 해제라는 두 개념의 차이를 이해하는 데 어려움을 겪는 개발자가 많습니다.
포그라운드 서비스는 앱이 사용자가 감지할 수 있는 작업을 실행하고 있으므로 메모리를 회수하기 위해 종료해서는 안 된다는 신호를 시스템에 보내는 수명 주기 API이지만, 화면이 꺼질 때 CPU가 절전 모드로 전환되는 것을 자동으로 방지하지는 않습니다. 반면 wake lock은 화면이 꺼져 있는 동안에도 CPU가 계속 실행되도록 특별히 설계된 메커니즘입니다.
사용자 작업을 계속하려면 포그라운드 서비스가 필요한 경우가 많지만 부분 wake lock 수동 획득은 CPU 활동 기간 동안 포그라운드 서비스와 함께만 필요합니다. 또한 기기를 절전 모드로 전환하지 않는 API를 이미 사용하고 있다면 wake lock을 사용할 필요가 없습니다.
기기를 절전 모드로 전환하지 않도록 올바른 API 선택의 흐름도를 참고하여 불필요한 시나리오에서 wake lock 획득을 방지하는 데 사용할 도구를 확실히 이해하세요.
서드 파티 라이브러리가 wake lock을 획득함
앱이 서드 파티 SDK 또는 시스템 API가 앱을 대신하여 보유한 과도한 절전 모드 해제로 인해 플래그가 지정되었음을 발견하는 것은 흔한 일입니다. 이러한 절전 모드 해제를 식별하고 해결하려면 다음 단계를 따르는 것이 좋습니다.
- Android vitals 확인: 과도한 부분 wake lock 대시보드에서 문제가 되는 wake lock의 정확한 이름을 찾습니다. 이 이름을 다른 API에서 생성된 절전 모드 해제 잠금 식별 안내와 교차 참조하여 알려진 시스템 API 또는 Jetpack 라이브러리에서 생성되었는지 확인합니다. 이 경우 API 사용량을 최적화해야 할 수 있으며 권장 안내를 참고할 수 있습니다.
- 시스템 트레이스 캡처: 절전 모드 해제 잠금을 쉽게 식별할 수 없는 경우 시스템 트레이스를 사용하여 절전 모드 해제 잠금 문제를 로컬에서 재현하고 Perfetto UI로 검사합니다. 이 블로그 게시물의 과도한 절전 모드 해제 잠금의 다른 유형 디버깅 섹션에서 자세히 알아보세요.
- 대체 평가: 비효율적인 서드 파티 라이브러리가 원인이고 배터리 수명을 고려하도록 구성할 수 없는 경우 SDK 소유자에게 문제를 알리고 대체 SDK를 찾거나 사내에서 기능을 빌드하는 것이 좋습니다.
일반적인 wake lock 시나리오
아래는 검토한 몇 가지 구체적인 사용 사례와 wake lock 구현을 최적화하기 위한 권장 경로입니다.
사용자 시작 업로드 또는 다운로드
사용 사례 예시:
- 사용자가 오프라인 액세스를 위해 대용량 파일의 다운로드를 트리거하는 동영상 스트리밍 앱
- 사용자가 알림 메시지를 통해 최근 사진 업로드를 트리거하는 미디어 백업 앱
Wake lock을 줄이는 방법:
- 수동 wake lock을 획득하면 안 됩니다. 대신 사용자 시작 데이터 전송 (UIDT) API를 사용하세요. 이는 사용자가 시작한 장기 실행 데이터 전송 작업의 지정된 경로이며 과도한 wake lock 계산에서 제외됩니다.
일회성 또는 주기적 백그라운드 동기화
사용 사례 예시:
- 앱은 오프라인 액세스를 위해 데이터를 가져오기 위해 주기적인 백그라운드 동기화를 실행합니다.
- 주기적으로 걸음 수를 가져오는 만보계 앱
Wake lock을 줄이는 방법:
-
수동 wake lock을 획득하면 안 됩니다. 일회성 또는 주기적 작업에 맞게 구성된 WorkManager를 사용합니다.
WorkManager는 작업을 일괄 처리하여 시스템 상태를 존중하며 최소 주기적 간격 (15분)이 있어 일반적으로 백그라운드 업데이트에 충분합니다. -
WorkManager또는 JobScheduler에서 생성된 wake lock이 wake lock 사용량이 많은 것으로 확인되면 특정 시나리오에서 완료되지 않도록 worker를 잘못 구성했을 수 있습니다. 특히 STOP_REASON_TIMEOUT이 자주 발생하는 경우 작업자 중지 이유를 분석하는 것이 좋습니다.
workManager.getWorkInfoByIdFlow(syncWorker.id)
.collect { workInfo ->
if (workInfo != null) {
val stopReason = workInfo.stopReason
logStopReason(syncWorker.id, stopReason)
}
}
- 작업자 중지 이유를 로깅하는 것 외에도 작업자 디버깅에 관한 문서를 참고하세요. 또한 시스템 트레이스 를 수집하고 분석하여 절전 모드가 획득되고 해제되는 시점을 파악하세요.
- 마지막으로 WHOOP와의 우수사례를 확인하세요. WHOOP는 worker 구성 문제를 발견하고 wake lock 영향력을 크게 줄일 수 있었습니다.
블루투스 통신
사용 사례 예시:
- 컴패니언 기기 앱에서 사용자에게 블루투스 외부 기기를 페어링하라는 메시지를 표시합니다.
- 컴패니언 기기 앱은 외부 기기의 하드웨어 이벤트와 사용자에게 표시되는 알림의 변경사항을 수신 대기합니다.
- 컴패니언 기기 앱의 사용자가 모바일과 블루투스 기기 간에 파일 전송을 시작합니다.
- 컴패니언 기기 앱은 블루투스를 통해 외부 기기에 가끔 펌웨어 업데이트를 실행합니다.
Wake lock을 줄이는 방법:
- 컴패니언 기기 페어링을 사용하여 블루투스 기기를 페어링하면 블루투스 페어링 중에 수동 wake lock을 획득하지 않아도 됩니다.
- 백그라운드에서 통신 안내를 참고하여 백그라운드 블루투스 통신 방법을 알아보세요.
-
지연된 커뮤니케이션이 사용자에게 영향을 미치지 않는 경우
WorkManager를 사용하는 것으로 충분한 경우가 많습니다. 수동 wake lock이 필요한 경우 블루투스 활동 또는 활동 데이터 처리 기간 동안만 wake lock을 유지하세요.
위치 추적
사용 사례 예시:
- 러닝 경로를 표시하는 등 나중에 업로드하기 위해 위치 데이터를 캐시하는 피트니스 앱
- 알림이나 위젯 UI에서 배송 진행 상황을 업데이트하기 위해 높은 빈도로 위치 데이터를 가져오는 음식 배달 앱
Wake lock을 줄이는 방법:
- 위치 사용 최적화에 관한 안내를 참고하세요. 배터리 효율성을 보장하기 위해 제한 시간을 구현하거나, 위치 요청 일괄 처리를 활용하거나, 수동적 위치 업데이트를 활용하는 것이 좋습니다.
- FusedLocationProvider 또는 LocationManager API를 사용하여 위치 업데이트를 요청하면 시스템은 위치 이벤트 콜백 중에 기기 절전 모드를 자동으로 트리거합니다. 이 짧은 시스템 관리 wake lock은 불필요한 부분적인 wake lock 계산에서 제외됩니다.
- 위치 데이터를 캐싱하기 위해 별도의 연속 wake lock을 획득하지 마세요. 중복됩니다. 대신 위치 이벤트를 메모리나 로컬 저장소에 유지하고 WorkManager를 활용하여 주기적으로 처리하세요.
override fun onCreate(savedInstanceState: Bundle?) {
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
// System wakes up CPU for short duration
for (location in locationResult.locations){
// Store data in memory to process at another time
}
}
}
}
고주파 센서 모니터링
사용 사례 예시:
- 걸음 수나 이동 거리를 수동으로 수집하는 만보계 앱
- 기기 센서의 급격한 변화를 실시간으로 모니터링하여 비상 상황 감지 또는 낙상 감지와 같은 기능을 제공하는 안전 앱
Wake lock을 줄이는 방법:
- SensorManager를 사용하는 경우 사용을 주기적인 간격으로 줄이고 사용자가 UI 상호작용을 통해 명시적으로 액세스 권한을 부여한 경우에만 사용합니다. CPU 절전 모드 해제 및 처리가 많이 발생하므로 고빈도 센서 모니터링은 배터리를 많이 소모할 수 있습니다.
- SensorManager를 사용하는 대신 걸음 수나 이동 거리를 추적하는 경우 Recording API를 활용하거나 헬스 커넥트를 사용하여 이전 및 집계된 기기 걸음 수에 액세스하여 배터리 효율적인 방식으로 데이터를 캡처하는 것이 좋습니다.
- SensorManager로 센서를 등록하는 경우 센서 일괄 처리를 활용하여 CPU 인터럽트 빈도를 최소화하도록 maxReportLatencyUs를 30초 이상으로 지정하세요. 이후 사용자 상호작용, 위치 검색, 예약된 작업과 같은 다른 트리거에 의해 기기가 절전 모드에서 해제되면 시스템은 캐시된 센서 데이터를 즉시 디스패치합니다.
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(this,
accelerometer,
samplingPeriodUs, // How often to sample data
maxReportLatencyUs // Key for sensor batching
)
- 앱에 위치 데이터와 센서 데이터가 모두 필요한 경우 이벤트 가져오기 및 처리를 동기화합니다. 위치 업데이트를 위해 시스템에서 유지하는 짧은 wake lock에 센서 판독값을 편승시켜 CPU를 깨워 두는 wake lock이 필요하지 않습니다. worker 또는 짧은 기간의 wake lock을 사용하여 이 결합된 데이터의 업로드 및 처리를 처리합니다.
원격 메시지
사용 사례 예시:
- 로컬 네트워크를 사용하여 연결된 외부 기기에서 발생하는 이벤트를 모니터링해야 하는 동영상 또는 소리 모니터링 컴패니언 앱
- 데스크톱 변형과의 네트워크 소켓 연결을 유지하는 메시지 앱
Wake lock을 줄이는 방법:
- 네트워크 이벤트를 서버 측에서 처리할 수 있는 경우 FCM을 사용하여 클라이언트에서 정보를 수신합니다. FCM 데이터의 추가 처리가 필요한 경우 신속한 작업자를 예약할 수 있습니다.
- 소켓 연결을 통해 클라이언트 측에서 이벤트를 처리해야 하는 경우 이벤트 인터럽트를 수신 대기하는 데 wake lock이 필요하지 않습니다. 데이터 패킷이 Wi-Fi 또는 모바일 데이터 라디오에 도착하면 라디오 하드웨어는 커널 wake lock 형태의 하드웨어 인터럽트를 트리거합니다.그런 다음 worker를 예약하거나 wake lock을 획득하여 데이터를 처리할 수 있습니다.
- 예를 들어 ktor-network를 사용하여 네트워크 소켓에서 데이터 패킷을 수신 대기하는 경우 패킷이 클라이언트에 전송되어 처리해야 할 때만 절전 모드 해제 잠금을 획득해야 합니다.
val readChannel = socket.openReadChannel()
while (!readChannel.isClosedForRead) {
// CPU can safely sleep here while waiting for the next packet
val packet = readChannel.readRemaining(1024)
if (!packet.isEmpty) {
// Data Arrived: The system woke the CPU and we should keep it awake via manual wake lock (urgent) or scheduling a worker (non-urgent)
performWorkWithWakeLock {
val data = packet.readBytes()
// Additional logic to process data packets
}
}
}
요약
백그라운드 동기화, 위치 추적, 센서 모니터링, 네트워크 통신과 같은 일반적인 사용 사례에 권장되는 솔루션을 채택하면 개발자는 불필요한 wake lock 사용을 줄일 수 있습니다. 계속해서 자세히 알아보려면 다른 기술 블로그 게시물을 읽거나 기술 동영상을 시청하여 wake lock을 발견하고 디버그하는 방법을 알아보세요. Android vitals wake lock 측정항목을 사용하여 앱 배터리 최적화 또한 업데이트된 절전 모드 해제 문서를 참고하세요. 기술 리소스를 지속적으로 개선할 수 있도록 문서 의견 설문조사에서 가이드에 대한 추가 의견을 공유해 주세요.
계속 읽기
-
방법
성능 레벨링 가이드에는 5가지 레벨이 있습니다. 최소한의 채택 노력 성능 도구를 소개하는 레벨 1부터 맞춤 성능 프레임워크를 유지할 리소스가 있는 앱에 적합한 레벨 5까지 살펴봅니다.
Alice Yuan • 읽는 데 9분 소요
-
방법
Android 스튜디오의 Gemini, Gemini CLI, Antigravity 또는 Claude Code, Codex와 같은 서드 파티 에이전트를 사용하는 경우에도 Google의 목표는 어디서나 고품질 Android 개발이 가능하도록 하는 것입니다.
Adarsh Fernando, Esteban de la Canal • 읽는 데 4분 소요
-
방법
온디바이스 모델과 클라우드 모델을 모두 사용하는 AI 지원 기능의 예를 제공하여 사용자에게 즐거운 경험을 선사할 수 있도록 영감을 드리고자 합니다.
Thomas Ezan, Ivy Knight • 전문 길이: 2분
소식 받아 보기
Android 개발 관련 최신 정보를 이메일로 받아 보세요.