Android WorkManager 제약 조건, 네트워크·배터리·재시도를 한 작업에 섞지 않는 법

라벨 없는 안드로이드 스마트폰과 빈 작업 카드, 충전 케이블과 무선 네트워크 장치가 자연광 책상에 놓인 모습
라벨 없는 안드로이드 스마트폰과 빈 작업 카드, 충전 케이블과 무선 네트워크 장치가 자연광 책상에 놓인 모습

AI를 활용하여 생성한 이미지입니다.

WorkManager 작업이 “가끔 늦게 실행된다”는 문제는 앱이 멈췄기 때문이 아니라 제약 조건을 모두 기다리는 설계 때문일 수 있어요. WorkRequest에는 실행 조건, 지연, 재시도 정책이 함께 들어가고, 여러 제약을 지정하면 모든 조건이 충족되어야 작업이 시작됩니다.[1][2] 따라서 네트워크와 배터리 조건을 넣은 뒤 실행 시각을 보장한다고 설명하면 안 됩니다.

제약 조건은 AND로 적용돼요

조건 뜻 실행이 늦어지는 상황
UNMETERED 종량제 네트워크가 아닌 연결을 요구해요. Wi-Fi가 끊기거나 모바일 데이터만 남았을 때
requiresCharging 충전 중일 때만 실행해요. 배터리 케이블이 빠진 상태
requiresBatteryNotLow 배터리가 낮지 않을 때 실행해요. 저전력 상태가 지속될 때
requiresStorageNotLow 저장공간이 부족하지 않을 때 실행해요. 사용 가능한 공간이 줄었을 때

공식 문서의 예시처럼 충전과 비종량제 네트워크를 동시에 요구하면 두 조건이 모두 맞아야 해요.[1] “Wi-Fi에 연결되면 즉시 업로드”가 목적이라면 충전 조건까지 함께 넣었는지 먼저 확인하세요. 반대로 큰 백업 파일처럼 배터리와 데이터 요금이 중요한 작업은 조건을 강하게 두는 편이 맞을 수 있습니다.

val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.UNMETERED)
    .setRequiresCharging(true)
    .setRequiresStorageNotLow(true)
    .build()

val request = OneTimeWorkRequestBuilder()
    .setConstraints(constraints)
    .build()

WorkManager.getInstance(context).enqueue(request)

조건이 실행 중 사라질 때를 따로 봐요

문서상 작업 실행 중 제약이 충족되지 않으면 WorkManager가 Worker를 중지하고, 조건이 다시 맞을 때 재시도할 수 있어요.[1] 네트워크가 잠깐 끊긴 상황에서 Worker 내부에 무한 재시도 루프를 만들면 시스템의 스케줄링과 겹칩니다. Worker는 현재 작업을 중단할 수 있게 설계하고, 다음 실행에서 이어받을 수 있는 checkpoint나 idempotent 업로드 키를 남겨야 해요.

작업이 중지됐는지, Result.retry()를 반환했는지, Result.failure()로 끝났는지는 구분해서 기록하세요. 이 세 가지를 모두 “실패”라고 표시하면 네트워크 조건 때문에 기다리는 작업을 오류로 오해하게 됩니다.[1][2]

retry와 backoff를 작업 성격에 맞춰요

WorkManager에서 재시도가 필요하면 Worker가 Result.retry()를 반환하고, WorkRequest의 backoff 정책에 따라 다시 예약됩니다. Android 문서는 backoff 지연의 최소값을 10초로 설명하고, 기본 정책은 지수 증가이며 기본 지연은 30초라고 안내합니다.[1] 네트워크 서버가 잠깐 응답하지 않는 작업에는 지수 backoff가 맞을 수 있지만, 잘못된 인증이나 서버가 영구적으로 거부한 요청에는 재시도만 늘려도 해결되지 않아요.

val request = OneTimeWorkRequestBuilder()
    .setBackoffCriteria(
        BackoffPolicy.EXPONENTIAL,
        WorkRequest.MIN_BACKOFF_MILLIS,
        TimeUnit.MILLISECONDS
    )
    .setConstraints(constraints)
    .build()

업로드 API가 일부 파일만 처리한 뒤 연결이 끊길 수 있으므로, 재시도 때 전체 파일을 무조건 다시 보내지 말고 서버의 업로드 상태나 클라이언트의 checksum을 확인하는 흐름을 두세요. WorkManager는 실행 시점을 보장하는 서비스가 아니라 조건이 맞을 때 작업을 예약하는 시스템이므로, 서버 쪽 중복 처리까지 대신해 주지 않습니다.[2]

주기 작업은 더 느슨하게 봐야 해요

PeriodicWorkRequest에 충전이나 비종량제 네트워크를 넣으면 반복 주기가 도래해도 조건이 맞을 때까지 실행이 밀릴 수 있어요. 공식 문서는 반복 구간 안에 조건이 맞지 않으면 특정 실행이 지연되거나 건너뛸 수 있다고 설명합니다.[1] 정각 동기화가 필요하다면 WorkManager만으로 시각을 보장하려 하지 말고, 서버 기준 시각과 마지막 성공 시각을 저장해 다음 실행에서 누락 구간을 보완하세요.

진단 로그는 상태 전이를 남겨요

기록할 값 확인할 이유
WorkRequest ID와 작업 종류 같은 작업의 재시도를 묶어요.
제약 조건과 관찰 시각 실행 대기 원인을 찾습니다.
Worker 시작·중지·종료 상태 조건 해제와 코드 예외를 구분해요.
retry 횟수와 backoff 정책 서버 오류가 반복되는지 봅니다.
서버 처리 키와 마지막 성공 범위 재시도 중복을 막아요.
  • 작업이 늦으면 네트워크·충전·배터리·저장공간 조건을 각각 읽기
  • 조건 대기와 Worker 예외를 같은 실패 코드로 합치지 않기
  • Result.retry()는 일시 오류에만 사용하고 영구 오류는 실패로 끝내기
  • 업로드·동기화는 재시도해도 중복되지 않는 키와 checkpoint를 저장하기
  • 주기 작업은 마지막 성공 시각을 기준으로 누락 구간 보완하기

WorkManager에서 실행이 늦다는 사실은 버그일 수도 있지만 정상적인 제약 결과일 수도 있어요. 먼저 작업이 어떤 조건을 기다리는지 기록하고, 그 다음에 배터리 최적화나 앱 프로세스 문제를 좁혀 가는 순서가 안전합니다.[1][2]

대기 중인 작업을 오류로 바꾸지 않는 로그

앱 화면에는 다음처럼 상태를 나누어 표시하는 편이 좋아요. ENQUEUED에 가까운 대기 상태라면 현재 제약 조건과 다음 확인 시각을 보여 주고, Worker가 실행됐다가 중단된 경우에는 네트워크나 충전 조건이 언제 풀렸는지 기록합니다. 반면 코드 예외로 failure가 된 작업은 사용자에게 재시도만 권하지 말고 입력 데이터와 서버 응답을 먼저 확인해야 해요.[1][2]

증상 확인할 값 수정 방향
오래 대기 네트워크·충전·저장공간 필요 이상의 조건을 제거하거나 안내를 보강해요.
짧은 간격으로 반복 retry 횟수·서버 상태 backoff와 영구 오류 판정을 조정해요.
같은 파일 중복 업로드 작업 ID·서버 idempotency key checkpoint와 중복 방지 키를 저장해요.

WorkManager가 조건을 만족할 때 다시 실행해 주더라도, 업로드 서버가 같은 요청을 두 번 받지 않는다는 보장은 없습니다. 작업 입력에 파일 해시나 논리적 작업 ID를 넣고, 서버가 이미 처리한 범위를 응답하게 만들면 조건 해제와 네트워크 재연결이 겹쳐도 복구가 쉬워져요. 이 부분은 WorkManager의 스케줄링과 앱의 데이터 설계를 분리해야 하는 이유입니다.[1][2]

정기 동기화의 현실적인 설계

정기 작업은 정확한 시각보다 마지막 성공 범위를 기준으로 설계하세요. 예를 들어 오전 실행이 지연됐다면 다음 실행에서 “현재 시각의 데이터만” 가져오지 말고 마지막 성공 시각 이후의 변경분을 조회하는 방식이 안전해요. 단, 서버가 변경 이력을 제공하지 않으면 작업이 누락될 수 있으므로 페이지 커서나 동기화 토큰을 저장해야 합니다.[1]

조건을 많이 넣을수록 배터리와 데이터 사용량은 줄어들 수 있지만 실행 지연은 커집니다. 반대로 조건을 모두 풀면 작업은 빨라져도 사용자 환경에서 배터리와 통신 비용이 커질 수 있어요. 제품 요구사항에 필요한 조건만 남기고, 나머지는 서버와 Worker의 작은 단위 처리로 해결하는 편이 운영하기 좋습니다.[3]

Android 설정과 백그라운드 작업 관련 글은 스마트기기 가이드 모음에서 이어집니다.

Sources

  1. Android Developers, Define work requests
  2. Android Developers, Getting started with WorkManager
  3. Android Developers API reference, Constraints

함께 읽을 글