일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 안드로이드 sunflower
- 부스트코스에이스
- 막내의막무가내 일상
- 막내의막무가내 코틀린
- 안드로이드
- 막내의막무가내 플러터 flutter
- 막내의막무가내 목표 및 회고
- 프로그래머스 알고리즘
- 2022년 6월 일상
- 막내의막무가내
- flutter network call
- 막내의막무가내 안드로이드 에러 해결
- 막내의막무가내 알고리즘
- 프래그먼트
- 막내의막무가내 프로그래밍
- 부스트코스
- 막내의막무가내 rxjava
- 막내의막무가내 안드로이드
- 막내의 막무가내 알고리즘
- 막내의막무가내 코볼 COBOL
- 막내의막무가내 안드로이드 코틀린
- Fragment
- 주택가 잠실새내
- 주엽역 생활맥주
- 막내의막무가내 코틀린 안드로이드
- 막무가내
- 막내의막무가내 SQL
- 안드로이드 Sunflower 스터디
- 막내의 막무가내
- 막내의막무가내 플러터
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[안드로이드] Android Jetpack WorkManager 백그라운드 작업처리 정리 본문
[안드로이드] Android Jetpack WorkManager 백그라운드 작업처리 정리
막무가내막내 2020. 8. 19. 00:55
[2021-04-14 업데이트]
[참고]
https://developer.android.com/guide/background?hl=ko
백그라운드 작업 처리시 안드로이드 개발자 문서에 적혀있듯이 다음과 같은 트리로 개발하면 됩니다.
즉시 실행해야한다 ? -> 코루틴, WorkManager
정확한 시간에 실행해야한다? -> AlaramManager
지연된 작업(Deferred)으로 실행해야한다? -> WorkManager
저는 이중에서 지연된 작업으로 노티가 가게하려고 WorkManager 를 처음 사용해봤는데요.
먼저 WorkManager는 Jeptack 아키텍처 구성요소 중 하나이며 WorkManager를 사용하면 작업을 쉽게 설정하고 시스템에 전달하여 지정한 조건에서 실행할 수 있습니다.
이에 대해서 제가 사용한 경험을 바탕으로 포스팅을 해볼려고 합니다.
저 같은 경우는 타 앱으로부터 FCM 을 받으면 해당 서비스에서 예약시간에 일어나야 할 일이면 분기처리하여 워크매니저를 실행했습니다. 또는 자신의 앱에서 노티피케이션 예약을 하는 경우 두 가지에 사용했습니다
WorkManager의 큰 흐름을 먼저 다음과 같은 프로세스로 이루어집니다.
WorkManager 클래스 생성 -> WorkManager Request 생성 -> Equeue Request (워크매니저 실행 요청) -> 상태 업데이트 얻기(작업 대기 및 수신)
이 프로세스에 대해 순서대로 알아보겠습니다.
1. 먼저 dependency를 추가하는데요. 저 같은 경우는 2번째 Kotlin + coroutines 만 추가했습니다.
dependencies {
def work_version = "2.4.0"
// (Java only)
implementation "androidx.work:work-runtime:$work_version"
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
// optional - RxJava2 support
implementation "androidx.work:work-rxjava2:$work_version"
// optional - GCMNetworkManager support
implementation "androidx.work:work-gcm:$work_version"
// optional - Test helpers
androidTestImplementation "androidx.work:work-testing:$work_version"
}
2. 백그라운드 작업을 할 WorkManager 를 만들어줍니다.
백그라운드 작업 만들기
WorkManager 클래스를 만드려면은Worker 클래스를 상속받고 context와 WorkerParameters를 필요로합니다. WorkerParamenteres는 말 그대로 인텐트 getExtras() 처럼 데이터를 전달받는데 사용됩니다. 그리고 doWork() 메서드를 오버라이딩 해야해야하는데 이것은 WorkManager에서 제공하는 백그라운드 스레드에서 동기식으로 실행됩니다
class ScheduledWorker(appContext: Context, workerParams: WorkerParameters) :
Worker(appContext, workerParams) {
override fun doWork(): Result {
// Get Notification Data
val title = inputData.getString(EXTRA_TITLE).toString()
val message = inputData.getString(EXTRA_BODY).toString()
// FCM 전송(따로 FCM 전송하는 Utils 클래스 만들었습니다.)
NotificationUtil(applicationContext).showNotification(
title,
message
)
//성공
return Result.success()
}
}
doWork()에서 반환된 Result는 WorkManager에 작업의 다음 상태를 알립니다.
- Result.success()를 통해 성공함
- Result.failure()를 통해 실패함
- Result.retry()를 통해 나중에 다시 시도해야 함
자세한 작업상태에 관한 설명은 다음을 참고해주세요 !
3. 저는 FCM Service 에서 페이로드를 검사하여 이게 지연되서 전송해야하는 넘겨온 데이터로 체크해서 바로 FCM 을 쏴주거나 WorkManager 를 사용해서 지연시키기 위해 scheduleAlarm() 이라는 메소드를 만들었습니다.
private fun workManagerAlarm(
scheduledTime : String, title : String, body : String
) {
//workMAnager 에 넘겨줄 파라미터 값
val data =
workDataOf(
EXTRA_BODY to body, EXTRA_TITLE to title
)
//지정한 시간의(schedudleTIme) 10분 이전의 타임스탬프 계산
val timeDiff =
scheduledTime.toLong() - System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(10)
//파라미터와 지연 시간 설정
val workRequest = OneTimeWorkRequestBuilder<ScheduledWorker>().setInputData(data)
.setInitialDelay(timeDiff, TimeUnit.MILLISECONDS).build()
//워크매니저 생성
val workManager = WorkManager.getInstance(applicationContext)
//워크매니저 실행
workManager.enqueue(workRequest)
}]
data 는 WorkManager 에 넘겨줄 파라미터를 지정하고 setInputData() Builder 함수로 넘겨주면 됩니다. 그리고 이것은 앞서 2번에서본 WorkManager 클래스에서 WorkerParameters에서 받을 수 있습니다. 저는 시간을 넘겨보았습니다.
그리고 지연되었으면 하는 시간을 계산하여 setInitialDelay() 함수로 설정할 수 있습니다.
그리고 저는 한번만 실행시킬것이기 떄문에 OntTimeWorkRequestBuilder를 사용했는데 주기적으로 사용할분들은 PeriodicWorkRequest를 사용하시면 됩니다.
이에 대한 자세한 내용은 밑을 참고해주세요 !!
작업 실행 방법 및 시기 구성
이때 OneTimeWorkRequestBuilder 에 대해서는 다음과 같습니다. WorkRequest는 작업이 언제 어떻게 실행되어야 하는지 정의합니다. 작업은 일회성이거나 주기적일 수 있습니다. 일회성 WorkRequest에는 OneTimeWorkRequest를 사용하고 주기적 작업에는 PeriodicWorkRequest를 사용합니다. 반복 작업 예약에 대한 자세한 내용은 반복 작업 문서를 참조하세요.
시스템에 작업 전달
workRequest를 정의했으면 이제 enqueue() 메서드를 사용한 WorkManager로 호출할 수 있습니다.
이 외에도 제약이나 반복 등 여러 옵션도 있는데 해당 사항들은 공식문서에서 보시면 됩니다.
[P.S]
주제와 별개로 WorkManger의 기능 중 하나를 더 알아보겠습니다. 다음사진과 같이 WorkManager의 상태를 옵저빙하여 처리할 수 있습니다. 사용방법은 getWorkInfoByIdLiveData() 매개변수로 WokrManagerRequest 의 ID 를 넣어주면 됩니다. !
이상 간략하게 정리해봤습니다. 이런식으로 사용해서 저는 제가 지정한 시간의 10분전에 알림을 받을 수 있었습니다. WorkManager 에는 이밖에도 체이닝, 스레딩 등 고급 개념이 많은데요. 해당 사항들은 공식문서를 참고해주시면 감사하겠습니다.
추가로 나중에 프로젝트에 추가로 적용했던 내용은 다음 링크에서도 볼 수 있습니다.
youngest-programming.tistory.com/367
댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!
'안드로이드 > 코틀린 & 아키텍처 & Recent' 카테고리의 다른 글
[안드로이드] 한국관광공사 API Service key error 처리 (SERVICE KEY IS NOT REGISTERED ERROR) (0) | 2020.08.30 |
---|---|
[안드로이드] 데이터바인딩 xml onclick 한글 파라미터 오류 해결 (2) | 2020.08.29 |
[안드로이드] Jetpack Navigation BottomNavigationView backstack error 처리 (0) | 2020.08.11 |
[안드로이드] DI Dagger2 @Singleton vs @Resuable 차이점 정리 (0) | 2020.08.08 |
[안드로이드] Lottie Animation 사용법 (0) | 2020.08.02 |