Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

작업 요청 정의

시작 가이드에서는 간단한 WorkRequest를 만들고 큐에 추가하는 방법을 살펴보았습니다.

이 가이드에서는 다음과 같은 일반적인 사용 사례를 처리하도록 WorkRequest 객체를 정의하고 맞춤설정하는 방법을 알아봅니다.

  • 일회성 및 반복 작업 예약
  • Wi-Fi 또는 충전과 같은 작업 제약조건 설정
  • 작업 실행의 최소 지연 보장
  • 재시도 및 백오프 전략 설정
  • 작업에 입력 데이터 전달
  • 태그를 사용하여 관련 작업 그룹화

개요

작업은 WorkManager에서 WorkRequest를 통해 정의됩니다. WorkManager로 작업을 예약하려면 먼저 WorkRequest 객체를 만들어 큐에 추가해야 합니다.

Kotlin


val myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest)

자바


WorkRequest myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest);

WorkRequest 객체에는 WorkManager에서 작업을 예약하고 실행하는 데 필요한 모든 정보가 들어 있습니다. 여기에는 작업을 실행하기 위해 충족해야 하는 제약조건, 지연 또는 반복 간격과 같은 예약 정보, 재시도 구성이 포함되며 입력 데이터를 기반으로 작업하는 경우 입력 데이터도 포함될 수 있습니다.

WorkRequest 자체는 추상적인 기본 클래스입니다. 요청을 만드는 데 사용할 수 있는 이 클래스의 파생된 구현은 OneTimeWorkRequest, PeriodicWorkRequest 두 가지입니다. 이름에서 알 수 있듯이 OneTimeWorkRequest는 일회성(반복 없음) 작업을 예약하는 데 유용하고 PeriodicWorkRequest는 일정 간격의 반복 작업을 예약하는 데 더 적합합니다.

일회성 작업 예약

추가 구성이 필요하지 않은 간단한 작업에는 정적 메서드 from을 사용합니다.

Kotlin


val myWorkRequest = OneTimeWorkRequest.from(MyWork::class.java)

자바


WorkRequest myWorkRequest = OneTimeWorkRequest.from(MyWork.class);

더 복잡한 작업에는 빌더를 사용할 수 있습니다.

Kotlin


val uploadWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       // Additional configuration
       .build()

자바


WorkRequest uploadWorkRequest =
   new OneTimeWorkRequest.Builder(MyWork.class)
       // Additional configuration
       .build();

주기적 작업 예약

경우에 따라 앱에서는 특정 작업을 주기적으로 실행해야 할 수 있습니다. 예를 들어 주기적으로 데이터를 백업하거나 최신 콘텐츠를 앱에 다운로드하거나 로그를 서버에 업로드해야 할 수 있습니다.

다음은 PeriodicWorkRequest를 사용하여 주기적으로 실행되는 WorkRequest 객체를 만드는 방법입니다.

Kotlin


val saveRequest =
       PeriodicWorkRequestBuilder<SaveImageToFileWorker>(1, TimeUnit.HOURS)
    // Additional configuration
           .build()

자바


PeriodicWorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class, 1, TimeUnit.HOURS)
           // Constraints
           .build();

이 예시에서 작업은 1시간 간격으로 예약됩니다.

간격 주기는 반복 사이의 최소 시간으로 정의됩니다. 작업자가 실행될 정확한 시간은 WorkRequest 객체에서 사용하는 제약조건과 시스템에서 실행하는 최적화에 따라 달라집니다.

가변 실행 간격

작업의 특성으로 인해 실행 타이밍에 민감하다면 그림 1과 같이 각 간격 주기 안에서 가변 기간 내에 실행되도록 PeriodicWorkRequest를 구성할 수 있습니다.

주기적 작업에 가변 간격을 설정할 수 있습니다. 반복 간격과 반복 간격 끝에서 특정 시간을 지정하는 가변 간격을 정의합니다. WorkManager에서는 주기마다 가변 간격 중 특정 시점에 작업 실행을 시도합니다.

그림 1. 반복 간격을 보여주는 다이어그램입니다. 작업을 실행할 수 있는 가변 기간이 포함되어 있습니다.

가변 기간으로 주기적 작업을 정의하려면 PeriodicWorkRequest를 만들 때 flexIntervalrepeatInterval과 함께 전달합니다. 가변 기간은 repeatInterval - flexInterval에서 시작하여 간격 끝으로 이동합니다.

다음은 한 시간마다 마지막 15분 동안 실행할 수 있는 주기적 작업의 예입니다.

Kotlin


val myUploadWork = PeriodicWorkRequestBuilder<SaveImageToFileWorker>(
       1, TimeUnit.HOURS, // repeatInterval (the period cycle)
       15, TimeUnit.MINUTES) // flexInterval
    .build()

자바


WorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class,
               1, TimeUnit.HOURS,
               15, TimeUnit.MINUTES)
           .build();

반복 간격은 PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS 이상이어야 하고 가변 간격은 PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS 이상이어야 합니다.

제약조건이 주기적 작업에 미치는 영향

제약조건을 주기적 작업에 적용할 수 있습니다. 예를 들어 사용자의 기기가 충전 중일 때만 작업이 실행되도록 작업 요청에 제약조건을 추가할 수 있습니다. 이 경우 정의된 반복 간격이 지나도 PeriodicWorkRequest는 조건이 충족될 때까지 실행되지 않습니다. 이로 인해 작업의 특정 실행이 지연되거나, 실행 간격 내에 조건이 충족되지 않으면 생략될 수도 있습니다.

작업 제약조건

제약조건은 최적의 조건이 충족될 때까지 작업이 지연되도록 합니다. WorkManager에서는 다음 제약조건을 사용할 수 있습니다.

NetworkType 작업을 실행하는 데 필요한 네트워크 유형을 제한합니다. 예: Wi-Fi(UNMETERED)
BatteryNotLow true로 설정하면 기기가 배터리 부족 모드인 경우 작업이 실행되지 않습니다.
RequiresCharging true로 설정하면 기기가 충전 중일 때만 작업이 실행됩니다.
DeviceIdle true로 설정하면 작업이 실행되기 전에 사용자 기기가 유휴 상태여야 합니다. 이는 사용자 기기에서 활발하게 실행되는 다른 앱의 성능에 부정적인 영향을 줄 수 있는 배치 작업을 실행하는 데 유용합니다.
StorageNotLow true로 설정하면 사용자의 기기 저장공간이 너무 부족한 경우 작업이 실행되지 않습니다.

일련의 제약조건을 만들고 이를 일부 작업과 연결하려면 Contraints.Builder()를 사용하여 Constraints 인스턴스를 만들어 WorkRequest.Builder()에 할당합니다.

예를 들어 다음 코드는 사용자의 기기가 충전 중이고 Wi-Fi에 연결되어 있을 때만 실행되는 작업 요청을 빌드합니다.

Kotlin


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

val myWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       .setConstraints(constraints)
       .build()

자바


Constraints constraints = new Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .setRequiresCharging(true)
       .build();

WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
               .setConstraints(constraints)
               .build();

여러 제약조건이 지정되면 제약조건이 모두 충족될 때만 작업이 실행됩니다.

작업 실행 중에 제약조건이 충족되지 않는 경우 WorkManager에서 작업자를 중지합니다. 그런 다음 모든 제약조건이 충족될 때 작업을 다시 시도합니다.

지연된 작업

작업이 큐에 추가될 때 작업에 제약조건이 없거나 모든 제약조건이 충족되는 경우 시스템에서 즉시 작업을 실행하기로 선택할 수 있습니다. 작업을 즉시 실행하지 않으려면 최소 초기 지연 후 시작하도록 작업을 지정할 수 있습니다.

다음은 작업이 큐에 추가되고 최소 10분 후에 실행되도록 설정하는 방법의 예입니다.

Kotlin


val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .setInitialDelay(10, TimeUnit.MINUTES)
   .build()

자바


WorkRequest myWorkRequest =
      new OneTimeWorkRequest.Builder(MyWork.class)
               .setInitialDelay(10, TimeUnit.MINUTES)
               .build();

이 예시에서는 OneTimeWorkRequest의 초기 지연을 설정하는 방법을 보여주지만 PeriodicWorkRequest의 초기 지연을 설정할 수도 있습니다. 이 경우 주기적 작업의 첫 번째 실행만 지연됩니다.

재시도 및 백오프 정책

WorkManager에서 작업을 다시 시도해야 하는 경우 작업자에서 Result.retry()를 반환하세요. 그러면 백오프 지연백오프 정책에 따라 작업이 다시 예약됩니다.

  • 백오프 지연은 첫 번째 시도 후 작업을 다시 시도하기 전에 기다릴 최소 시간을 지정합니다. 이 값은 10초(또는 MIN_BACKOFF_MILLIS) 미만일 수 없습니다.

  • 백오프 정책은 다음 재시도의 백오프 지연이 시간 경과에 따라 증가하는 방식을 정의합니다. WorkManager에서는 두 가지 백오프 정책 LINEAR, EXPONENTIAL을 지원합니다.

모든 작업 요청에는 백오프 정책과 백오프 지연이 있습니다. 기본 정책은 10초 지연이 있는 EXPONENTIAL이지만 작업 요청 구성에서 재정의할 수 있습니다.

다음은 백오프 지연 및 정책을 맞춤설정하는 예입니다.

Kotlin


val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .setBackoffCriteria(
       BackoffPolicy.LINEAR,
       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
       TimeUnit.MILLISECONDS)
   .build()

자바


WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
               .setBackoffCriteria(
                       BackoffPolicy.LINEAR,
                       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
                       TimeUnit.MILLISECONDS)
               .build();

이 예시에서는 최소 백오프 지연이 최소 허용 값 10초로 설정됩니다. 정책이 LINEAR이므로 재시도 간격은 새로 시도할 때마다 약 10초씩 증가합니다. 예를 들어 Result.retry()로 끝나는 첫 번째 실행은 10초 후에 다시 시도되고 작업이 다음 시도 후에도 계속 Result.retry()를 반환하면 20초, 30초, 40초 등으로 재시도 간격이 늘어납니다. 백오프 정책이 EXPONENTIAL로 설정된 경우 재시도 길이는 20, 40, 80 등의 시퀀스로 이어집니다.

태그 작업

모든 작업 요청에는 고유 식별자가 있습니다. 고유 식별자는 작업을 취소하거나 작업 진행 상황을 관찰하기 위해 나중에 작업을 식별하는 데 사용할 수 있습니다.

논리적으로 관련된 작업 그룹이 있다면 이러한 작업 항목에 태그를 지정하는 것도 유용할 수 있습니다. 태그를 사용하면 작업 요청 그룹을 함께 실행할 수 있습니다.

예를 들어 WorkManager.cancelAllWorkByTag(String)는 특정 태그가 있는 모든 작업 요청을 취소하고 WorkManager.getWorkInfosByTag(String)는 현재 작업 상태를 확인하는 데 사용할 수 있는 WorkInfo 객체 목록을 반환합니다.

다음 코드는 'cleanup' 태그를 작업에 추가하는 방법을 보여줍니다.

Kotlin


val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .addTag("cleanup")
   .build()

자바


WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
       .addTag("cleanup")
       .build();

마지막으로 단일 작업 요청에 여러 태그를 추가할 수 있습니다. 내부적으로 이러한 태그는 문자열 집합으로 저장됩니다. 작업 요청에서 WorkRequest.getTags()를 통해 태그 집합을 검색하세요.

입력 데이터 할당

작업을 실행하려면 입력 데이터가 작업에 필요할 수 있습니다. 예를 들어 이미지 업로드를 처리하는 작업은 이미지의 URI를 입력으로 업로드해야 할 수 있습니다.

입력 값은 Data 객체에 키-값 쌍으로 저장되고 작업 요청에서 설정할 수 있습니다. WorkManager에서는 작업을 실행할 때 작업에 입력 Data를 제공합니다. Worker 클래스는 Worker.getInputData()를 호출하여 입력 인수에 액세스할 수 있습니다. 아래 코드는 입력 데이터가 필요한 Worker 인스턴스를 만들어 작업 요청에서 전송하는 방법을 보여줍니다.

Kotlin


// Define the Worker requiring input
class UploadWork(appContext: Context, workerParams: WorkerParameters)
   : Worker(appContext, workerParams) {

   override fun doWork(): Result {
       val imageUriInput =
           inputData.getString("IMAGE_URI") ?: return Result.failure()

       uploadFile(imageUriInput)
       return Result.success()
   }
   ...
}

// Create a WorkRequest for your Worker and sending it input
val myUploadWork = OneTimeWorkRequestBuilder<UploadWork>()
   .setInputData(workDataOf(
       "IMAGE_URI" to "http://..."
   ))
   .build()

자바


// Define the Worker requiring input
public class UploadWork extends Worker {

   public UploadWork(Context appContext, WorkerParameters workerParams) {
       super(appContext, workerParams);
   }

   @NonNull
   @Override
   public Result doWork() {
       String imageUriInput = getInputData().getString("IMAGE_URI");
       if(imageUriInput == null) {
           return Result.failure();
       }

       uploadFile(imageUriInput);
       return Result.success();
   }
   ...
}

// Create a WorkRequest for your Worker and sending it input
WorkRequest myUploadWork =
      new OneTimeWorkRequest.Builder(UploadWork.class)
           .setInputData(
               new Data.Builder()
                   .putString("IMAGE_URI", "http://...")
                   .build()
           )
           .build();

마찬가지로 Data 클래스를 사용하여 반환 값을 출력할 수 있습니다. 입력 및 출력 데이터는 입력 매개변수 및 반환된 값 섹션에서 자세히 다룹니다.

다음 단계

상태 및 관찰 페이지에서 작업 상태 및 작업 진행 상황을 모니터링하는 방법을 자세히 알아봅니다.