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
를 간단하게 업데이트할 수 있습니다.
큐에 추가된 작업을 업데이트하려면 다음 단계를 따르세요.
- 큐에 추가된 작업의 기존 ID 가져오기: 업데이트하려는 WorkRequest의 ID를 가져옵니다. 이 ID는
getWorkInfo
API를 사용하거나 큐에 추가하기 전에 공개 속성WorkRequest.id
로 나중에 검색할 수 있도록 초기 WorkRequest에서 ID를 수동으로 유지하여 검색할 수 있습니다. - 새 WorkRequest 만들기: 새
WorkRequest
를 만들고WorkRequest.Builder.setID()
를 사용하여 기존WorkRequest
의 ID와 일치하도록 ID를 설정합니다. - 제약 조건 설정:
WorkRequest.Builder.setConstraints()
를 사용하여 WorkManager의 새 제약 조건을 전달합니다. - 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
의 생성을 가져오려면 다음 단계를 따르세요.
- WorkInfo:
WorkManager.getWorkInfoById()
를 호출하여WorkRequest
에 상응하는WorkInfo
의 인스턴스를 가져옵니다.WorkInfo
를 반환하는 여러 메서드 중 하나를 호출할 수 있습니다. 자세한 내용은 WorkManager 참조를 확인하세요.
- getGeneration:
WorkInfo
인스턴스에서getGeneration()
를 호출합니다. 반환된Int
는WorkRequest
의 세대에 해당합니다.- 세대 필드나 속성은 없으며
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
를 사용하는 워크플로가 사용됩니다.
예를 들어 enqueueUniquePeriodicWork
를 PeriodicWorkRequest
와 함께 사용할 경우 ExistingPeriodicWorkPolicy.UPDATE
정책을 사용하여 새 PeriodicWorkRequest
를 초기화할 수 있습니다. 고유한 이름이 같은 대기 중인 PeriodicWorkRequest
가 있으면 WorkManager는 새 사양으로 업데이트합니다. 이 워크플로에서는 updateWork()
를 사용하지 않아도 됩니다.