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
