들어가며..
면접 질문으로 4대 컴포넌트에 대한 질문을 종종 받았던 기억이 있다.
업무를 하며 기교만 늘어서인가, 이런 원론적인 질문에 제대로 답하지 못하는 자신의 헛점을 메꾸고자 내가 아는 선에서 개념을 정리하고자 한다.
빈약하고 허술할 순있지만, 최대한 아는 내용을 담으려고 노력하겠다.
최신 수정일: 2024.01.17
Service Component
안드로이드의 4대 컴포넌트 중 하나로, 안드로이드 개발자라면 Activity 다음으로 많이 접하게 되는 컴포넌트라고 생각된다.
Service는 사용자 인터페이스(UI) 없이 앱의 백그라운드에서 긴 시간이 걸리는 작업을 수행하는 컴포넌트이다.
서비스는 보통 두가지로 구분된다.
- Foreground Service
- Background Service
Background? Foreground? Why???
서론에서 작성했지만, 서비스는 백그라운드에서 긴 작업을 수행하는 컴포넌트다.
앞서, 서비스는 보통 두가지로 구분된다고 하였다. 간략하게 짚어보자.
Background Service는 사용자에게 보이지 않고 묵시적으로 실행되며, 앱이 전면부(사용 중)에 있는 동안 백그라운드에서 수행되어야하는 작업을 위해 사용한다. 때문에 사용자가 작동 여부를 알지 못할 수 있다.
적용 예시로는 데이터 동기화, 네트워크 요청, DB 업데이트 등이 있다.
반면, Foreground Service는 명시적인 작업에 주로 사용되는데, 위치 추적과 미디어 플레이 등, 사용자에게 직접적으로 보이지 않더라도 백그라운드에서 수행되어야 하는 작업을 위해 사용된다.
예를 들면 Nike Run처럼 위치를 추적하는 앱이나 Spotify / Youtue Music처럼 미디어를 플레이하는 앱에서 주로 사용된다.
우리는 타이머, 음악 재생, 파일 다운로드와 같은 작업이 사용자와 앱이 상호작용을 하지 않더라도 백그라운드에서 주어진 작업을 수행한다는 것을 알고 있다.
그럼 동일하게 UI도 필요없고 백그라운드에서 작업을 수행하는 이들을 왜 굳이 Background와 Foreground를 나눌까?
서비스가 나뉘는 이유는 사용자 경험과 시스템 리소스에 대한 서비스의 우선순위를 관리하기 위함이다.
서비스가 백그라운드에서만 돌게되면, Android 6.0(Api level 23, 마시멜로)부터 도입된 배터리 절약 기능인 Doze 모드로 인하여 리소스 관리 명목 하에, 시스템에 의해 무작위로 kill을 당할 수가 있다.
당장 전면부에서 사용되는 앱이 더 많은 자원(메모리)을 요구한다면, 백그라운드에서 장시간 동작 중인 다른 앱의 서비스는 리소스를 낭비 하는 것으로 인식되어 결코 안전하지 못한 것이다.
Foreground Service
Forground Services perform operations that are noticeable to user.
(포그라운드 서비스는 사용자에게 눈에 띄는 작업을 수행합니다.)
이 문장은 Android Devleopements에 작성되어있는 문구로, Foreground Service를 한 문장으로 가장 잘 나타낸 것이라 생각한다.
Foreground Service는 사용자 인지(Notification) 라는 특성을 지닌다.
이는 사용자가 서비스의 동작을 인지할 수 있도록 가시적인 알림을 제공한다는 것이다.
이런 알림은 사용자뿐만이 아닌 시스템에도 '중요한 서비스'가 동작 중임을 인지시킨다.
즉, Foreground Service는 시스템에 의해 종료가 되지 않는다.
때문에 포그라운드 서비스를 실행하면 일반적으로 사용자가 중지하지 않는 한, 계속 실행된다.
또, 포그라운드 서비스는 활성화된 액티비티와 동급의 우선순위를 가지는데, 이 덕분에 메모리가 부족하더라도 시스템에 의해 강제 종료될 확률이 매우 낮다.
(하지만 절대적인 것은 아니다. 일부 디바이스는 자체 시스템 설정으로 배터리 절약을 위해 강제로 정리하기도 한다. Don’t Kill My App에서 해당 디바이스들을 확인 가능하다.)
포그라운드 서비스는 사용자가 서비스의 동작을 인지할 수 있도록, 반드시 알림(Notification)을 제공해야한다.
포그라운드 서비스는 사용자에게 보이는 알림(ongoing notification)과 연결이 되어있어야 한다.
알림을 제공하는 이유는 앞서도 정리했지만, 다음과 같다.
- 사용자에게 실행 중인 서비스의 존재를 인지시킨다.
- 서비스의 시스템 리소스 사용을 정당화함으로써, 시스템 의한 강제 종료를 예방하기 위함이다.
또한, 알림에는 서비스를 중지할 수 있는 상호작용을 포함시킬 수 있기 때문에 사용자가 직접 서비스를 중지하여 시스템 리소스를 절약하도록 유도 할 수도 있다.
알림(Notification)에 대한 자세한 내용은 이 글을 참조 바란다.
Foreground Service 생성 방법
간단하게 포그라운드 서비스를 생성하는 방법을 살펴보겠다. 디테일한 코드는 아니며 간단하게 '이런게 필요하다' 정도만 작성한다.
Foreground Service 생성 방법
1. 서비스 클래스 생성: Service 클래스를 상속받아 서비스를 생성한다.
2. Notification 생성: 사용자에게 보여줄 알림을 생성한다.
3. 서비스를 Foreground로 설정: startForeground 메서드를 사용하여 서비스를 Foreground로 설정하고 알림을 전달한다.
4. 서비스 시작: startForeground 메서드를 호출해 서비스를 실행한다.
간단한 코드
class SimpleForegroundService : Service() {
override fun onCreate() {
super.onCreate()
val notification = {
// ✅ 알림 생성 코드를 이곳에 작성
}
startForeground(1, notification) // ✅ 서비스를 Foreground로 설정
}
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onDestory(){
super.onDestroy()
stopService(Intent)
}
}
주의사항으로는 서비스가 더 이상 필요하지 않은 경우, stopForeground
와 stopService
를 사용해 중지해야한다는 것이다.
다음 글에서는 Foreground Service를 실제로 만들어 보며 어떻게 프로젝트에 적용이 가능한지 확인해보자.
'Android > Basic' 카테고리의 다른 글
Retrofit2: 기본 사용 (1) | 2023.11.30 |
---|---|
[Android Basic] Activities & Activity Lifecycle (0) | 2023.10.16 |
[Android: Basic] NotificationCompat.Builder의 Style (0) | 2023.08.23 |
[Android: Basic] Notification (0) | 2023.08.23 |
Moshi Converter (0) | 2023.02.25 |