[Android] Jetpack WorkManager란?
Android

[Android] Jetpack WorkManager란?

728x90

 

 

WorkManager란?

 앱이 종료되거나 기기가 다시 시작되더라도 실행이 예상되는 연기 가능한 비동기 작업을 쉽게 예약할 수 있는 라이브러리 Background task 구현, 스케쥴 등을 쉽게 처리할 수 있도록 만든 기능이다.

 

 

WorkManager 기능

  1. Job 스케쥴링 : Job을 스케쥴링 할 수 있다.
  2. Job의 상태 모니터링 : 실시간으로 처리되는지 상태를 알 수 있다.
  3. Constraint : 원하는 조건에 Job이 동작하도록 제약을 줄 수 있다.
  4. 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/

 

728x90