Android

WorkManager (3) : 작업 관리하기

까망사과 2022. 12. 5. 06:00

작업 예약하기

작업을 예약하려면 WorkRequest 객체를 WorkManager의 예약 큐에 추가해야 한다.

 

WorkManager 객체는 WorkManager.getInstance(Context)를 호출하여 액세스한다. 그러고 나서 enqueue(WorkRequest)에 WorkRequest 객체를 전달한다.

val myWork: WorkRequest = // ... OneTimeWorkRequest or PeriodicWorkRequest
WorkManager.getInstance(requireContext()).enqueue(myWork)

 

고유 작업 예약하기

작업을 예약할 때 고유 이름을 설정하면 해당 이름을 가진 작업 인스턴스가 하나만 존재하게 된다. 이렇게 하면 같은 작업이 중복 예약되는 문제를 방지할 수 있다. 작업의 고유 이름은 작업 ID와는 다르게 개발자가 직접 설정할 수 있으며 사용자가 읽을 수 있다. 또한 태그는 여러 작업 인스턴스에 추가할 수 있는 반면 고유 이름은 단일 작업 인스턴스에만 설정할 수 있다.

 

고유 작업을 예약하려면 작업 실행 횟수에 따라 다음 WorkManager의 메서드를 선택하여 호출한다.

  • enqueueUniqueWork()
    일회성 고유 작업을 예약한다.
  • enqueueUniquePeriodicWork()
    주기성 고유 작업을 예약한다.

두 메서드 모두 다음 세 파라미터를 수신한다.

  • uniqueWorkName: String
    작업에 설정할 고유 이름
  • existingWorkPolicy: ExistingWorkPolicy
    (일회성 작업) 같은 고유 이름을 가진 작업과 충돌할 경우 동작 정책을 나타내는 enum 값
    • REPLACE
      기존 작업을 취소하고 새 작업으로 대체
    • KEEP
      새 작업을 무시하고 기존 작업을 유지
    • APPEND
      새 작업을 기존 작업의 끝에 추가. 기존 작업이 취소되거나 실패하면 새 작업도 이를 따른다.
    • APPEND_OR_REPLACE
      새 작업을 기존 작업의 끝에 추가. 기존 작업이 취소되거나 실패하더라도 새 작업은 실행된다.
  • existingPeriodicWorkPolicy: ExistingPeriodicWorkPolicy
    (주기성 작업) 같은 고유 이름을 가진 작업과 충돌할 경우 동작 정책을 나타내는 enum 값
    • CANCEL_AND_REENQUEUE
      기존 작업을 취소하고 새 작업으로 대체
    • KEEP
      새 작업을 무시하고 기존 작업을 유지
    • UPDATE
      기존 작업을 취소하지 않고 다음 실행 시 새 설정으로 업데이트
  • work: WorkRequest
    예약하고자 하는 작업
val sendLogsWorkRequest = PeriodicWorkRequestBuilder<SendLogsWorker>(24, TimeUnit.HOURS)
    .setConstraints(Constraints.Builder()
        .setRequiresCharging(true)
        .build())
    .build()
           
WorkManager.getInstance(this)
    .enqueueUniquePeriodicWork(
        "sendLogs",
        ExistingPeriodicWorkPolicy.KEEP,
        sendLogsWorkRequest)

 

작업 정보 확인하기

ID, 태그, 고유 이름으로 WorkManager를 쿼리한 결과인 WorkInfo 객체는 예약한 작업에 대한 다음 정보를 포함한다.

  • ID
  • 추가된 태그
  • 현재 작업 상태
  • 출력 데이터
  • 실행 시도 횟수

 

WorkInfo 객체는 WorkManager의 다음 메서드를 사용하여 가져올 수 있다.

  • getWorkInfoById(UUID): ListenableFuture<WorkInfo>
    ID가 일치하는 작업에 대한 WorkInfoListenableFuture 반환
  • getWorkInfosByTag(String): ListenableFuture<List<WorkInfo>>
    전달한 태그를 포함하는 모든 작업에 대한 WorkInfo의 ListenableFuture 리스트 반환
  • getWorkInfosForUniqueWork(String): ListenableFuture<List<WorkInfo>>
    전달한 고유 이름을 가진 일련의 작업에 대한 WorkInfo의 ListenableFuture 리스트 반환

작업 정보를 관찰할 수 있도록 LiveData로 변환하는 메서드도 있다.

  • getWorkInfoByIdLiveData(UUID): LiveData<WorkInfo>
  • getWorkInfosByTagLiveData(String): LiveData<list<WorkInfo>>
  • getWorkInfosForUniqueWork(String): LiveData<List<WorkInfo>>

 

다음은 ID로 WorkManager를 쿼리하여 가져온 WorkInfo를 포함하는 LiveData를 관찰하고 해당 작업을 성공했을 경우 Snackbar 메시지를 표시하는 예시다.

workManager.getWorkInfoByIdLiveData(syncWorker.id)
    .observe(viewLifecycleOwner) { workInfo ->
        if (workInfo?.state == WorkInfo.State.SUCCEEDED) {
            Snackbar.make(
                requireView(),
                R.string.work_completed,
                Snackbar.LENGTH_SHORT).show()
        }
    }

 

WorkManager을 더욱 복합적으로 쿼리하려면 WorkQuery를 사용할 수 있다. WorkQuery 객체는 WorkQuery.Builder 클래스를 통해 생성하며 다음 메서드를 사용하여 ID, 태그, 상태, 고유 이름을 쿼리 구성 요소로 포함할 수 있다. 각 구성 요소는 AND로 연결되며 구성 요소 안의 각 값은 OR로 연결된다. 생성한 WorkQuery 객체를 WorkManager#getWorkInfos(WorkQuery) 또는 WorkManager#getWorkInfosLiveData(WorkQuery)에 전달하여 조건에 해당하는 작업 정보 목록을 가져올 수 있다.

 

다음 예시는 "syncTag"가 태그이고 상태가 FAILED 또는 CANCELLED이고 고유 이름이 "preProcess" 또는 "sync"인 모든 작업에 대한 정보를 가져온다.

val workQuery = WorkQuery.Builder
    .fromTags(listOf("syncTag"))
    .addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED))
    .addUniqueWorkNames(listOf("preProcess", "sync"))
    .build()

val workInfos: ListenableFuture<List<WorkInfo>> = workManager.getWorkInfos(workQuery)

 

작업 취소하기

WorkManager의 다음 메서드를 사용하여 ID, 태그, 고유 이름이 일치하는 작업을 취소할 수 있다.

  • @NonNull Operation cancelWorkById(@NonNull UUID)
  • @NonNull Operation cancelAllWorkByTag(@NonNull String)
  • @NonNull Operation cancelUniqueWork(@NonNull String)

작업이 이미 완료된 상태라면 아무 변화도 없고 그렇지 않은 경우 CANCELLED 상태로 변경된다. 작업이 현재 실행 중인 경우 Worker 객체의 ListenableWorker#onStopped() 콜백이 호출된다.

'Android' 카테고리의 다른 글

Retrofit2로 JSON 데이터 요청하기  (0) 2023.02.21
WorkManager (4) : 작업 체이닝  (0) 2022.12.10
WorkManager (2) : 작업 상태  (0) 2022.12.02
WorkManager (1) : 작업 설정/예약하기  (0) 2022.12.02
DataStore  (0) 2022.11.30