본문 바로가기
개발/안드로이드

Jetpack - Workmanager (2)

by darksilber 2019. 10. 31.
반응형

출처 - https://beomseok95.tistory.com/194?category=1048223

Jetpack - Workmanager (2)

워크매니저 자세히 살펴보기

1. 작업상태 확인

완료 된 작업에 대해 사용자에게 알림을 통보해 주거나, 화면에 표시된 프로그래스바를 감춰야 하기도 하고,다시 새로운 작업을 실행 해야 하기도 합니다.

 WorkManager.getInstance().getWorkInfoByIdLiveData(work.id)
        .observe(lifecycleOwner, Observer { workInfo ->
            if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
                // 작업 완료
            }
        })

work 는 request입니다. Requst에서 아이디를 가져와 라이브데이터로 관찰할 수 있습니다.

 

지정된 Observer 에 작업의 상태는 WorkState 객체로 전달됩니다.

WorkState 클래스의 구조는 아래와 같은 구조로 getState() 메서드는 ENQUEUED, RUNNING, SUCCEEDED, FAILED, BLOCKED, CANCELLED 의 6개의 상태를 반환합니다.

 

 

 

2. 작업간의 정보전달

어느 한 작업이 끝나고 , 다음작업을 실행할 때 다음 작업에세 데이터를 전달해야할 필요가 있을수도 있습니다.

val input = mapOf("input" to "this is input data")

val inputData = Data.Builder().putAll(input).build()

// 코틀린의 경우 Map 에 제공되는 인라인 함수 toWorkData() 를 이용해 쉽게 Data 객체를 생성할수도 있습니다.
//val inputData = input.toWorkData()

 val compressWork = OneTimeWorkRequestBuilder()
            .setInputData(inputData)
            .build()

val uploadWork = OneTimeWorkRequestBuilder().build()

WorkManager.getInstance()?.apply {
        beginWith(compressWork).then(uploadWork).enqueue()
}

 

 

Worker 클래스에는 전달받은 Data 객체를 반환하는 getInputData() 메서드가 존재하며

이 메서드를 이용해서 Data 객체를 반환받아 사용합니다.

 

class CompressWorker : Worker() {
    override fun doWork(): Result {
    
        val fileName = inputData.getString("input", "")
        
        return Result.SUCCESS
    }
}

3. 작업 취소

WorkRequest 의 객채 생성시 고유한 ID 값을 가지는 UUID 객체가 생성되어 저장됩니다.

이 ID 는 작업을 취소하기 위해서도 사용됩니다.

WorkManager 의 cancelWorkById() 메서드는 인자로 UUID 객체를 사용하며,

주어진 UUID 값을 가진 작업을 취소합니다.

//큐에 작업추가
WorkManager.getInstance()?.enqueue(cacelWork)

// ID(UUID) 를 이용하여 작업을 취소
WorkManager.getInstance()?.cancelWorkById(cacelWork.id)

UUID 뿐 아니라 직접 태그를 추가하고 , 태그를 이용하여 취소도 가능합니다.

val cacelWork = OneTimeWorkRequestBuilder()
                .addTag("cancel work tag")
                .addTag("Hello work")
                .build()
                
                
//태그를 이용한 작업 취소
WorkManager.getInstance()?.cancelAllWorkByTag("cancel work tag")

WorkManager 에서 취소 하고자 하는 작업이 이미 완료 된 작업이라면 취소 메서드는 아무 기능도 하지 않습니다. 아직 실행 전 큐에 담긴 상태라면 실행하지 않고 취소 됩니다.

하지만 이미 실행된 작업을 임의로 멈추지 않습니다. 작업에 대해 멈춰야 한다고 Worker 의 Stopped 플래그 와 Cancelled 플래그를 통하여 알려줍니다. 개발자는 이 플래그를 isStopped() 메서드 와 isCancelled() 메서드를 이용하여 작업 취소에 대비하는 코드를 작성할수 있습니다.

class CancelWorker: Worker() {
    override fun doWork(): Result {
        
        if (isStopped) {
          // 작업이 멈추었을때를 대비한 코드를 이곳에 작성합니다.
          
          if (isCancelled) {
             // 작업이 취소 되었을때를 대비한 코드를 이곳에 작성합니다.
          }   
        }

        return Result.SUCCESS
    }
}

isStopped() 는 작업의 중지, isCancelled() 는 작업의 취소를 뜻합니다.

isStopped() 은 어느시점에 다시 작업이 실행될 것이고 ,

isCancelled()는 작업이 다시 시작될 여지가 없습니다.

 

 

4. Unique Work - 유일작업

백그라운드 작업을 처리하다보면 빈번이 일어나는 상황이 바로 작업의 관리 입니다.

중복 작업 되지 않아야 하는 상황에서는 같은 작업이 이미 추가되어 있지 않은지 파악해야 하고, 새로운 작업으로 대체 해야 한다면 이전 작업을 찾아서 취소 해야합니다. 이미 추가된 작업 이후에 또다른 작업이 되어야 하는 경우는 이전 작업이 끝날때까지 상황을 추적하여 종료시점에 다시 작업을 추가해야 합니다.

 

WorkManager에서는 UniqueWork를 위해 아래와 같은 메소드를 지원합니다.

 

  • beginUniqueWork(uniqueWorkName,ExistingWorkPolicy,request) - oneTimeRequest
  • enqueueUniquePeriodicWork(uniqueWorkName,ExistingPeriodicWorkPolicy,request) - PreriodicRequset

ExistingWorkPolicy 의 플래그

  • KEEP : 작업 A 가 실행 대기 중 이거나 실행 중이면 작업 B 는 WorkManager 의 큐에 추가 되지 않습니다. 작업 A 의 실행이 이미 끝났다면 작업 B 는 큐에 추가 됩니다.
  • REPLACE : 작업 A 를 작업 취소 하고 작업 B 를 큐에 추가 합니다.
  • APPEND : 작업 B 를 BLOCKED 상태로 대기 시킵니다. A 작업이 완료되면 작업 B 를 큐에 추가 합니다.

ExistingPeriodicWorkPolicy 의 플래그

  • KEEP : 위와 동일
  • REPLACE : 위와 동일

 

ex)

 workManager.enqueueUniquePeriodicWork("periodUniqueWork", ExistingPeriodicWorkPolicy.REPLACE , workRequest)

 

 

5. 체인기반 작업

fun chainWorks(filter1: Work, filter2: Work, compress: Work, upload: Work) {
  WorkManager.getInstance()
    .beginWith(listOf(filter1, filter2)) //동시실행
    .then(compress) //beginWith 끝난뒤
    .then(upload) //compress 끝난뒤
    .enqueue()
}
반응형

'개발 > 안드로이드' 카테고리의 다른 글

MapView ScrollView 터치이벤트  (0) 2020.01.28
recyclerview 로딩 중 빛나는 표시효과(shimmer)  (0) 2020.01.21
Jetpack - WorkManager(1)  (0) 2019.10.31
WorkManager 사용법  (0) 2019.10.31
Paging library 사용법  (0) 2019.10.29

댓글