Constraint(제약 사항) 추가하기
- WorkRequestBuilder에 제약사항을 추가할 수 있다. 제약 사항은 Constraints.Builder()를 통해 작성할 수 있다.
// in view(activity, fragment) or viewmodel
val constraints = Constraints.Builder()
.setRequiresCharging(true) // 충전 상태일 때만 작동한다.
.setRequiresBatteryNotLow(true) // 배터리 부족상태가 아닐 때만 작동한다.
.build()
val workRequest = OneTimeWorkRequestBuilder<SomeWorker>()
.setConstraints(constraints)
.build()
태그 추가 및 작업 관리하기
- 모든 작업 요청에 고유 식별자인 태그를 넣어 해당 작업을 취소하거나 진행 상황을 확인할 수 있다. WorkRequestBuilder에 addTag()를 통해 태그를 작성하여 식별할 수 있도록 만들어준다.
- 태그 값을 통하여 취소는 간단하게 할 수 있으며 작업 진행 상황은 반환되는 WorkInfo 객체를 통해 확인할 수 있다.
- WorkInfo State
- BLOCKED
- CANCELLED
- ENQUEUED
- FAILED
- RUNNING
- SUCCEEDED
// add tag
val workRequest = OneTimeWorkRequestBuilder<SomeWorker>()
.addTag("some_worker") // Add this method
.build()
// cancel work
workManager.cancelAllWorkByTag("some_worker")
// get work info to livedata
val workInfos = workManager.getWorkInfosByTagLiveData("some_worker")
// observe example in view
workInfos.observe(lifecycleOwner) { workInfos ->
if (listOfWorkInfo.isNullOrEmpty()) return@observe
val workInfo = workInfos[0]
if (workInfo.state.isFinished) { // SUCCEEDED or FAILED or CANCELLED
hideProgressBar()
} else {
showProgressBar()
}
}
여러 작업 체이닝하기
- 작업을 순차적 또는 동시에 실행되도록 만드는 WorkRequest를 생성할 수 있다.
val work1 = OneTimeWorkRequestBuilder<Work1Worker>().build()
// ... val work2 ~
// workManager is WorkManager Instance.
workManager
.beginWith(listOf(work1, work2))
.then(work3)
.then(work4)
.enqueue()
- enqueue() 내에 WorkRequest를 보내는 것이 아니라, beginWith()를 통해 시작할 작업을 넘긴다. 이 때 두개 이상의 작업을 동시에 시작하려면 List에 담아 넘겨준다.
- 위 작업이 끝나면 시작할 작업들을 then() 메서드를 통해 작성한다.(계속 체이닝 가능)
- 작업 큐에 보낼 테스크를 모두 작성하였으면, enqueue()를 통해 큐에 최종적으로 추가하여 작업을 실행한다.
Worker와 데이터 주고받기
- Key-value 쌍으로 이루어진 Worker의 Data로 데이터를 담아 Worker로 보낼 수 있으며 작업이 완료된 후 데이터를 받아올 수 있다.
// input data for worker
val inputData = Data.Builder().apply {
putString("secret_key", "genius-dev")
build()
}
val workRequest = OneTimeWorkRequestBuilder<SomeWorker>()
.setInputData(inputData)
.build()
workManager.enqueue(workRequest)
// in Worker
class BlurWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params) {
override fun doWork(): Result {
val secretKey = inputData.getString("secret_key")
//..
val outputData = workDataOf("public_key" to "android")
Result.success(outputData)
}
}
// in view(activity, fragment) or viewmodel
workInfos.observe(lifecycleOwner) { workInfos ->
if (listOfWorkInfo.isNullOrEmpty()) return@observe
val workInfo = workInfos[0]
if (workInfo.state.isFinished) {
hideProgressBar()
val outputData = workInfo.outputData.getString("public_key") // <<<< HERE
Toast.makeText(this, "worker output data : $outputData", Toast.LENGTH_SHORT).show()
} else {
showProgressBar()
}
}
- WorkRequest에 setInputDta()를 통해 Data를 보낼 수 있으며, 이때 Data를 만들때에는 Data.Builder()를 사용한다.
- Worker 클래스의 생성자인 WorkerParameters로 데이터는 전달되며, getInputData() 메서드를 통해 쉽게 받아올 수 있다. 작업을 완료한 후에 Result.Success()에 Data를 전달한다.
- Data를 만들 때 Data.Buider()를 편하게 작성해주는 함수인 workDataOf()도 존재한다.