선생님, 개발을 잘하고 싶어요.

[WorkManager] 안드로이드 백그라운드 작업, WorkManager 사용하기 본문

개발/android 개발

[WorkManager] 안드로이드 백그라운드 작업, WorkManager 사용하기

알고싶은 승민 2020. 6. 14. 20:36

목적

반드시 종료되어야 하고, 지연될 수 있는 작업을 백그라운드에서 실행하고 싶을 때 사용한다.

매인 클래스

  • Worker: 실제 수행할 작업을 doWork 인터페이스에 정의
  • WorkRequest: Work를 수행하도록 요청한다.
    • 수행할 Worker를 전달해야 한다.
    • 수행할 제약 조건인 Constraints도 전달 가능하다.
  • WorkManager: WorkRequest들을 스케쥴링 한다.
  • Constraints: Work가 실행될 조건을 명세한다.

Worker

  • WorkManager에 의해서 생성된다.

    • 내가 직접 생성하는 것이 아니기에, Worker의 멤버 변수가 유지될 것이라는 생각은 버려야
  • applicationContext로 앱 컨텍스트에 접근 가능하다.

  • 작업의 성공 여부에 따라 Result를 반환한다.

    • 성공시: Result.success
    • 실패시: Result.failure
  • inputData → 이 프로퍼티로, WorkRequest에 등록한 InputData를 읽을 수 있다.

→ 개념적으로 input과 output이 존재하는 함수처럼 생각할 수 있다.

→ input을 그대로 output으로 넘겨주는 완벽히 functional 한 Worker도 생각할 수 있겠다.

→ output 데이터를 넘기지 않으면, 알아서 input 데이터가 다음 Worker로 넘어가나...?

→ ㄴㄴ 그냥 소비됨

→ 미들웨어 같은 Worker를 추가할 수 도 있어 보인다... 🤔

→ 다른 Worker와 Chaining되게 동작될 수 있으니, 동작은 매우 atomic하면 좋다.

→ 살짝, 시퀀스 처리와 비슷한 느낌이네.

Data 클래스

  • Worker의 input / output
  • key / value 페어를 가지고 있다.
  • 제한된 작은 크기로 운용된다. (10KB)
  • Data.Builder 를 사용해서 제작
  • WorkRequest를 통해서 Worker에게 전달
  • intent에서 정보를 읽어오는 것처럼, 정보를 읽어오는게 가능하다.

WorkManager

  • enqueue: WorkRequest를 비동기적으로 수행한다.
  • beginWith: 작업 Chain을 정의하는 WorkContinuation를 생성한다. then으로 Reuqest를 엮는다.
  • beginUniqueWork: 온전히 Atomic한 Chain을 정의한다.
    • ExistingWorkPolicy.KEEP → 이미 해당 id의 작업이 있다면, 아무것도 하지 않는다.

    • ExistingWorkPolicy.REPLACE → 이미 해당 id의 작업이 있다면, 체인을 취소하고 삭제한다. 다시 시작한다.

      → 정리 작업이 마지막에 들어가는 작업 같은 경우에는 정리가 안될 우려가 있네.

    • ExistingWorkPolicy.APPEND → 이미 해당 id의 작업이 있다면, 그 작업이 끝난 이후 실행한다.

  • cancelUniqueWork: Unique Chain id로 지정된 Chain 취소
    • 특정 Request만 취소할 수도 있음 (cancel 관련 함수가 3-5개 정도 있음)

→ WorkContinuation이 온전히 Request의 Chain을 다룬다면, then으로 이 Chain을 연결하지 못하는 이유는 무엇인가?

  • Request를 스케쥴링 한다.
  • Requesrt를 Chaining한다.
  • Worker의 output이 다음 Chain Worker의 input으로!

Work의 라이프사이클

  • WorkRequest로 부터 WorkInfo를 받을 수 있다.

  • WorkInfo는 다음과 같은 상태를 가지고 있다.

    • BLOCKED
    • CANCELLED
    • ENQUEUED
    • FAILED
    • RUNNING
    • SUCCEEDED

    → Rx Stream으로 받는 방법이 존재하는가? 어떤 모습인가?

  • 받아오는 법

    • getWorkInfoByIdLiveData → id를 사용
    • getWorkInfosForUniqueWorkLiveData → chain name을 사용해서, chain의 모든 요소들의 WorkInfo를 받아옴
    • getWorkInfosByTagLiveData → tag를 상용해서 모든 요소의 WorkInfo를 받아옴
  • WorkInfo가 종료되었으면 outputData 프로퍼티를 통해, 출력 정보를 받아올 수 있다.

참고자료

공식 문서: https://developer.android.com/topic/libraries/architecture/workmanager/basics?hl=ko

공식 블로그 문서: https://medium.com/androiddevelopers/introducing-workmanager-2083bcfc4712 

코드랩: https://codelabs.developers.google.com/codelabs/android-workmanager/?hl=ko#0

Comments