WorkManager란?
앱이 종료되거나 기기가 다시 시작되더라도 실행이 예상되는 연기 가능한 비동기 작업을 쉽게 예약할 수 있는 라이브러리 Background task 구현, 스케쥴 등을 쉽게 처리할 수 있도록 만든 기능이다.
WorkManager 기능
- Job 스케쥴링 : Job을 스케쥴링 할 수 있다.
- Job의 상태 모니터링 : 실시간으로 처리되는지 상태를 알 수 있다.
- Constraint : 원하는 조건에 Job이 동작하도록 제약을 줄 수 있다.
- Chaining Task : 여러 Job을 우리가 정한 순서대로 실행되도록 할 수 있다.
WorkManager 주요 클래스
1. Worker
백그라운드에서 수행될 태스크를 의미한다. 추상 클래스인 Worker를 상속한 클래스를 구현하고 동작할 태스크를 구현해야 한다.
2. WorkRequest
WorkManager에 수행할 태스크를 요청할 때 사용되는 클래스이다. 수행할 Worker를 등록해야 하고, 한번만 실행할 것인지 주기적으로 실행할 것인지 설정할 수 있다. (OneTimeWorkRequest, PeriodicWorkRequest)
3. WorkManager
WorkManager에 WorkRequest들이 추가되며, 설정에 맞게 태스크를 동작시킨다.
4. WorkInfo
WorkManager에 추가된 태스크들의 상태를 나타낸다. Enqueue, Running, Success, Fail 등의 태스크의 현재 상태를 알 수 있다. WorkManager는 WorkInfo를 LiveData로 제공하기 때문에 Observer를 붙여 상태를 감시할 수 있다.
WorkManager 예제
SimpleWorker.kt
class SimpleWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
val number = 10
val result = number * number
SystemClock.sleep(5000)
Log.d("SimpleWorker", "SimpleWorker finished: $result")
return Result.success()
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
startSimpleWorkerBtn.setOnClickListener {
/* request 객체 */
val simpleRequest = OneTimeWorkRequest.Builder(SimpleWorker::class.java).build()
/* WorkManager 객체 */
val workManager = WorkManager.getInstance()
/* WorkManager에 WorkRequest 추가 */
workManager.beginWith(simpleRequest).enqueue()
}
}
}
WorkInfo
val workInfo = workManager.getWorkInfoByIdLiveData(simpleRequest.id)
workInfo.observe(this, Observer<WorkInfo> { info ->
val workFinished = info.state.isFinished
simpleWorkStatusText.text = when (info.state) {
WorkInfo.State.SUCCEEDED,
WorkInfo.State.FAILED -> {
"work status: ${info.state}, finished: $workFinished"
}
else -> {
"work status: ${info.state}, finished: $workFinished"
}
}
})
WorkInfo의 State는 태스크의 상태를 나타내며 다음과 같다.
- ENQUEUED
- RUNNING
- SUCCEEDED
- FAILED
- BLOCKED
- CANCELLED
InputData, OutputData
Worker에 인자로 숫자를(Input data) 전달하고, Worker 안에서 사용할 수 있다.
val inputData = Data.Builder()
.putInt("input", 5)
.build()
val simpleRequest = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
.setInputData(inputData)
.build()
inputData.getInt("input", 0)
마찬가지로 Worker에서 outputData를 사용해 밖으로 값을 전달할 수 있다.
val outputData = Data.Builder()
.putInt("output", result)
.build()
return Result.success(outputData)
status.observe(this, Observer<WorkInfo> { info ->
val result = info.outputData.getInt("output", 0) // 0은 defaultValue
})
Cancel
WorkManager를 통해 모든 태스크를 취소하거나 또는 특정 ID나 TAG를 갖고 있는 태스크를 취소할 수 있다. cancelAllWorkByTag , cancelWorkById , cancelAllWork 등을 사용할 수 있다.
cancelSimpleWorkerBtn.setOnClickListener {
val workManager = WorkManager.getInstance()
workManager.cancelWorkById(simpleRequest.id)
}
Constraint
Constraints.Builder 로 Constraint객체를 만들 수 있다.
val constraints = Constraints.Builder()
.setRequiresCharging(true) // 디바이스가 충전 중일때만 가능
.build()
val simpleRequest = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
.setInputData(inputData)
.setConstraints(constraints)
.build()
Chaining Task
WorkManager는 여러 Task를 순차적으로 실행할 수 있도록 기능을 제공한다. 가장 먼저 실행되는 태스크는 WorkManager.beginWith로 설정하고, 그 다음 실행되는 태스크는 WorkManager.then으로 설정할 수 있다.
val simpleRequest = OneTimeWorkRequest.Builder(SimpleWorker::class.java)
.build()
val simple2Request = OneTimeWorkRequest.Builder(Simple2Worker::class.java)
.build()
workManager
.beginWith(simpleRequest)
.then(simple2Request)
.enqueue()
아래 그림처럼 좀 더 복잡한 Chaining 태스크도 설정할 수 있다.
WorkManager.getInstance()
.beginWith(TASK1, TASK2, TASK3)
.then(TASK4)
.then(TASK5, TASK6)
.enqueue();
출처 : https://codechacha.com/ko/android-jetpack-workmanager/
'Android' 카테고리의 다른 글
[Android] MediatorLiveData가 동작하지 않을 때 (1) | 2020.05.13 |
---|---|
[Android] LiveData 변형하기 (Transformations) (0) | 2020.04.22 |
[Android] Jetpack LiveData란? (0) | 2020.04.19 |
[Android] Jetpack ViewModel이란? (0) | 2020.04.18 |
[Android] Navigation Drawer 안에서 ExpandableListView 사용하기 (6) | 2020.04.11 |