1. WorkManager란?

어플리케이션 프로세스가 현재 실행되는지와 상관없이 수행해야하는 백그라운드 작업을 처리하는 API

그래서 즉시 실행하지 않아도 괜찮지만, 언젠가는 꼭 실행되어야하는 작업에 사용


2. 특징

1) 실행 보장

- 앱이 꺼지거나 시스템이 재시작되어도 설정된 작업이 취소되지 않고 나중에라도 반드시 실행

 

2) 조건부 실행

- 와이파이가 연결됐을때만, 충전중일때만 같은 특정 조건 충족될때 작업이 시작하도록 할 수 있음

 

3) 체이닝

- 여러 작업을 순차적/병렬로 연결해서 복잡한 작업흐름을 만들 수 있음


3. 구성 요소

1) Worker / CoroutineWorker

- 백그라운드 스레드에서 동기적으로 작업을 수행하는 클래스

- doWork() 함수 내에 할 일 작성

- 비동기적으로 작업하고 싶다면 CoroutineWorker 사용

 

2) WorkRequest

- 작업의 실행 조건 정의

- OneTimeWorkRequest : 한번만 실행되는 WorkRequest

- PeriodicWorkRequest : 일정 주기로 반복 실행되는 WorkRequest

 

3) WorkManager

- WorkRequest를 큐에 넣고 관리하는 클래스


4. 주의사항

주기적으로 수행해야 하는 작업을 맡기는 경우 간격을 적절히 둬야 함(최소 15분 이상)

1) 원인

- 스마트폰을 사용하지 않으면 배터리 절약을 위해 Doze모드(절전모드)에 진입하는데 이 때 불필요하게 계속 기기가 깨어나게 됨

- 여러 앱의 백그라운드 작업을 모았다가 한꺼번에 처리하는 방식인데, 이렇게되면 네트워크 연결같은 동작을 한번 하고 작업을 몰아서 할 수 있지만 계속 작업을 하면 네트워크 연결같은 작업도 계속 반복해야 함

- 내부적으로 API24의 JobScheduler를 사용하는데 JobScheduler가 15분보다 짧으면 실행 안하게 되어있음

 

2) 15분보다 자주 실행하려면?

- Foreground Service나 AlarmManger 활용


5. 사용 방법

1) Dependency 추가

- 꼭 2.8.1 버전이어야 하는건 아니고 최신버전 나오면 바꿔도 됨

implementation("androidx.work:work-runtime-ktx:2.8.1")

 

2) Worker 구현

- Worker 혹은 CoroutineWorker를 상속받고 doWork를 오버라이딩한다

class MyWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
    override suspend fun doWork(): Result {
    
    	// do something...
        
        return withContext(Dispatchers.IO) { // 코루틴을 어느 Dispatcher에게 맡길지
            return@withContext try {
                // do something...
                Result.success()
            } catch (throwable: Throwable) {
                Result.failure()
            }
        }
    }
}

 

3) WorkManager 구현 및 WorkRequest

private val workManager = WorkManager.getInstance(context)

fun enqueue() {
    val workerBuilder = OneTimeWorkRequestBuild<MyWorker>() // 한번만 실행하는 WorkRequest일 때
    val workerBuilder = PeriodicWorkRequestBuild<MyWorker>() // 일정 주기로 실행하는 WorkRequest일 때
    workManager.enqueue(workerBuilder.build())
}

 

4) 체이닝 사용 방법

- CleanupWorker -> BlurWorker -> SaveImageToFileWorker순으로 체인을 만들어 실행함

private val workManager = WorkManager.getInstance(context)

fun enqueue() {
    var continuation = workManager.beginWith(OneTimeWorkRequest.from(CleanupWorker::class.java))
    // continuation에는 WorkContinuation 객체가 들어가며 체인의 첫번째 작업 요청이 있는 WorkRequest 체인의 시작점이 된다.
    
    val blurBuilder = ~~
    continuation = continuation.then(blurBuilder.build())
    
    val save = OneTimeWorkRequestBuilder<SaveImageToFileWorker>().build()
	continuation = continuation.then(save)
    
    continuation.enqueue() // 작업 시작
}

 

이어서 작성중....

 

 

※ 참고 문헌

- android basics with compose

  - https://developer.android.com/courses/android-basics-compose/course?hl=ko