250x250
Notice
12-08 02:11
관리 메뉴

막내의 막무가내 프로그래밍 & 일상

[안드로이드] Android Jetpack WorkManager 백그라운드 작업처리 정리 본문

안드로이드/코틀린 & 아키텍처 & Recent

[안드로이드] Android Jetpack WorkManager 백그라운드 작업처리 정리

막무가내막내 2020. 8. 19. 00:55
728x90

 

 

[2021-04-14 업데이트]

 


[참고]

https://developer.android.com/guide/background?hl=ko

 

백그라운드 처리 가이드  |  Android 개발자  |  Android Developers

백그라운드 데이터 처리는 사용자의 기대에 부응하고 사용자에게 도움이 되는 Android 애플리케이션을 개발하는 데 있어 중요한 부분입니다. 이 가이드에서는 백그라운드 작업 카테고리를 정의��

developer.android.com

https://namget.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-AlarmManager-With-Notification-Example-%EC%95%8C%EB%9E%8C%EB%A7%A4%EB%8B%88%EC%A0%80%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-%ED%91%B8%EC%89%AC%EC%83%9D%EC%84%B1-%EC%98%88%EC%A0%9C

 

[안드로이드] AlarmManager With Notification Example (알람매니저를 이용하여 푸쉬생성 예제)

 안녕하세요 YTS 입니다. 오늘은 알람매니저(AlarmManager)를 이용하여 푸쉬(Notification)를 생성하는 예저를 다루어볼까합니다. 추가적으로 JobScheduler를 이용하여 백그라운드에서도 반응하도록 예제

namget.tistory.com

 

 

 

백그라운드 작업 처리시 안드로이드 개발자 문서에 적혀있듯이 다음과 같은 트리로 개발하면 됩니다.

즉시 실행해야한다 ? -> 코루틴, 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()를 통해 나중에 다시 시도해야 함

 

자세한 작업상태에 관한 설명은 다음을 참고해주세요 !

https://developer.android.com/topic/libraries/architecture/workmanager/how-to/states-and-observation?hl=ko&authuser=1

 

 

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를 사용합니다. 반복 작업 예약에 대한 자세한 내용은 반복 작업 문서를 참조하세요. 

 

https://developer.android.com/topic/libraries/architecture/workmanager/how-to/define-work?hl=ko&authuser=1#schedule_one-time_work
https://developer.android.com/topic/libraries/architecture/workmanager/how-to/define-work?hl=ko&authuser=1#schedule_periodic_work

시스템에 작업 전달

workRequest를 정의했으면 이제 enqueue() 메서드를 사용한 WorkManager로 호출할 수 있습니다.

이 외에도 제약이나 반복 등 여러 옵션도 있는데 해당 사항들은 공식문서에서 보시면 됩니다.

 

 


[P.S]

주제와 별개로 WorkManger의 기능 중 하나를 더 알아보겠습니다. 다음사진과 같이 WorkManager의 상태를 옵저빙하여 처리할 수 있습니다. 사용방법은 getWorkInfoByIdLiveData() 매개변수로 WokrManagerRequest 의 ID 를 넣어주면 됩니다. !

 

이상 간략하게 정리해봤습니다. 이런식으로 사용해서 저는 제가 지정한 시간의 10분전에 알림을 받을 수 있었습니다. WorkManager 에는 이밖에도 체이닝, 스레딩 등 고급 개념이 많은데요. 해당 사항들은 공식문서를 참고해주시면 감사하겠습니다. 

 

 

추가로 나중에 프로젝트에 추가로 적용했던 내용은 다음 링크에서도 볼 수 있습니다.

youngest-programming.tistory.com/367

 

[코틀린] 안드로이드 AlarmManager 와 WorkManager 사용하여 10분전 알림 만들기

github.com/mtjin/NoMoneyTrip mtjin/NoMoneyTrip SKT 2020 스마트 관광앱 공모전 '무전여행' 앱. Contribute to mtjin/NoMoneyTrip development by creating an account on GitHub. github.com 안녕하세요 AlarmM..

youngest-programming.tistory.com

 

 

댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!

728x90
2 Comments
댓글쓰기 폼