이미 큐에 추가된 작업을 업데이트합니다.

WorkManager를 사용하면 이미 큐에 추가한 후 WorkRequest를 업데이트할 수 있습니다. 이는 제약 조건을 자주 변경하거나 즉석에서 worker를 업데이트해야 하는 대규모 앱에서 자주 필요합니다. WorkManager 버전 2.8.0부터는 updateWork() API를 사용하여 이를 실행할 수 있습니다.

updateWork() 메서드를 사용하면 수동으로 새 항목을 취소하고 대기열에 추가하는 프로세스를 거치지 않고 즉석에서 WorkRequest의 특정 측면을 변경할 수 있습니다. 이렇게 하면 개발 프로세스가 크게 간소화됩니다.

작업 취소 피하기

일반적으로 기존 WorkRequest를 취소하고 새 WorkRequest를 큐에 추가하지 않아야 합니다. 이렇게 하면 앱에서 특정 작업을 반복할 수 있고 상당한 양의 추가 코드를 작성해야 할 수 있습니다.

WorkRequest를 취소할 때 문제가 발생할 수 있는 경우를 보여주는 다음 예를 고려하세요.

  • 백엔드 요청: 서버로 전송할 페이로드를 계산하는 동안 Worker를 취소하면 새 Worker를 다시 시작하여 비용이 많이 들 수 있는 페이로드를 다시 계산해야 합니다.
  • 예약: PeriodicWorkRequest를 취소하고 새 PeriodicWorkRequest를 동일한 일정으로 실행하려면 시차를 계산하여 새 실행 시간이 이전 작업 요청과 일치하도록 해야 합니다.

updateWork() API를 사용하면 새 요청을 취소하고 대기열에 추가할 필요 없이 작업 요청의 제약 조건과 기타 매개변수를 업데이트할 수 있습니다.

작업을 취소해야 하는 경우

updateWork()를 호출하는 대신 WorkRequest를 직접 취소해야 하는 경우가 있습니다. 이는 큐에 추가한 작업의 기본 특성을 변경하려고 할 때 해야 하는 작업입니다.

과제물을 업데이트해야 하는 경우

사용자의 사진을 매일 백업하는 사진 앱이 있다고 가정해 보겠습니다. PeriodicWorkRequest가 큐에 추가되었습니다. WorkRequest에는 기기를 충전하고 Wi-Fi에 연결해야 하는 제약 조건이 있습니다.

하지만 사용자는 급속 충전기를 사용해 하루에 20분 동안만 기기를 충전합니다. 이 경우 앱이 WorkRequest를 업데이트하여 충전 제약 조건을 완화함으로써 기기가 완전히 충전되지 않은 경우에도 사진을 계속 업로드할 수 있도록 할 수 있습니다.

이 경우 updateWork() 메서드를 사용하여 작업 요청의 제약 조건을 업데이트할 수 있습니다.

과제 업데이트 방법

updateWork() 메서드를 사용하면 새 항목을 취소하고 큐에 추가할 필요 없이 기존 WorkRequest를 간단하게 업데이트할 수 있습니다.

큐에 추가된 작업을 업데이트하려면 다음 단계를 따르세요.

  1. 큐에 추가된 작업의 기존 ID 가져오기: 업데이트하려는 WorkRequest의 ID를 가져옵니다. 이 ID는 getWorkInfo API를 사용하거나 큐에 추가하기 전에 공개 속성 WorkRequest.id로 나중에 검색할 수 있도록 초기 WorkRequest에서 ID를 수동으로 유지하여 검색할 수 있습니다.
  2. 새 WorkRequest 만들기: 새 WorkRequest를 만들고 WorkRequest.Builder.setID()를 사용하여 기존 WorkRequest의 ID와 일치하도록 ID를 설정합니다.
  3. 제약 조건 설정: WorkRequest.Builder.setConstraints()를 사용하여 WorkManager의 새 제약 조건을 전달합니다.
  4. updateWork 호출: 새 WorkRequest를 updateWork()에 전달합니다.

직장 예시 업데이트

다음은 updateWork() 메서드를 사용하여 사진을 업로드하는 데 사용되는 WorkRequest의 배터리 제약 조건을 변경하는 방법을 보여주는 Kotlin의 코드 스니펫 예입니다.

suspend fun updatePhotoUploadWork() {
    // Get instance of WorkManager.
    val workManager = WorkManager.getInstance(context)

    // Retrieve the work request ID. In this example, the work being updated is unique
    // work so we can retrieve the ID using the unique work name.
    val photoUploadWorkInfoList = workManager.getWorkInfosForUniqueWork(
        PHOTO_UPLOAD_WORK_NAME
    ).await()

    val existingWorkRequestId = photoUploadWorkInfoList.firstOrNull()?.id ?: return

    // Update the constraints of the WorkRequest to not require a charging device.
    val newConstraints = Constraints.Builder()
        // Add other constraints as required here.
        .setRequiresCharging(false)
        .build()

    // Create new WorkRequest from existing Worker, new constraints, and the id of the old WorkRequest.
    val updatedWorkRequest: WorkRequest =
        OneTimeWorkRequestBuilder<MyWorker>()
            .setConstraints(newConstraints)
            .setId(existingWorkRequestId)
            .build()

    // Pass the new WorkRequest to updateWork().
    workManager.updateWork(updatedWorkRequest)
}

결과 처리

updateWork()에서 ListenableFuture<UpdateResult>를 반환합니다. 지정된 UpdateResult에는 WorkManager가 변경사항을 적용할 수 있었는지 여부를 나타내는 여러 값 중 하나가 있을 수 있습니다. 또한 변경사항을 적용할 수 있었던 시기를 나타냅니다.

자세한 내용은 updateWork() UpdateResult 참조를 확인하세요.

세대와 함께 작업 추적하기

WorkRequest를 업데이트할 때마다 generation이 1씩 증가합니다. 이를 통해 현재 큐에 추가된 WorkRequest를 정확하게 추적할 수 있습니다. 세대를 통해 작업 요청을 관찰, 추적, 테스트할 때 더 세밀하게 제어할 수 있습니다.

WorkRequest의 생성을 가져오려면 다음 단계를 따르세요.

  1. WorkInfo: WorkManager.getWorkInfoById()를 호출하여 WorkRequest에 상응하는 WorkInfo의 인스턴스를 가져옵니다.
    • WorkInfo를 반환하는 여러 메서드 중 하나를 호출할 수 있습니다. 자세한 내용은 WorkManager 참조를 확인하세요.
  2. getGeneration: WorkInfo 인스턴스에서 getGeneration()를 호출합니다. 반환된 IntWorkRequest의 세대에 해당합니다.
    • 세대 필드나 속성은 없으며 WorkInfo.getGeneration() 메서드만 있습니다.

트랙 생성 예

다음은 WorkRequest의 세대를 가져오기 위해 위에서 설명한 워크플로의 구현 예입니다.

// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)

// Retrieve WorkInfo instance.
val workInfo = workManager.getWorkInfoById(oldWorkRequestId)

// Call getGeneration to retrieve the generation.
val generation = workInfo.getGeneration()

작업 업데이트 정책

이전에는 주기적 작업을 업데이트할 때 권장되는 방법은 ExistingPeriodicWorkPolicy.REPLACE 정책을 사용하여 PeriodicWorkRequest를 큐에 추가하는 것이었습니다. 동일한 고유 id가 있는 대기 중인 PeriodicWorkRequest가 있는 경우 새 작업 요청이 취소되고 삭제됩니다. 이제 이 정책은 지원 중단되며 대신 ExistingPeriodicWorkPolicy.UPDATE를 사용하는 워크플로가 사용됩니다.

예를 들어 enqueueUniquePeriodicWorkPeriodicWorkRequest와 함께 사용할 경우 ExistingPeriodicWorkPolicy.UPDATE 정책을 사용하여 새 PeriodicWorkRequest를 초기화할 수 있습니다. 고유한 이름이 같은 대기 중인 PeriodicWorkRequest가 있으면 WorkManager는 새 사양으로 업데이트합니다. 이 워크플로에서는 updateWork()를 사용하지 않아도 됩니다.