안드로이드/Deep in the AOS

Service :: 앱 구성 요소 4대 컴포넌트 [ Deep in the AOS ]

Android Develop에서는 Service를 이렇게 설명합니다.

백그라운드에서 오래 실행되는 작업을 수행할 수 있는 애플리케이션의 구성 요소이며
사용자 인터페이스를 제공하지 않습니다.

다른 애플리케이션 구성 요소가 서비스를 시작할 수 있으며,
사용자가 다른 애플리케이션으로 전환하더라도 백그라운드에서 계속 실행됩니다.

구성 요소를 서비스에 바인딩해 서비스와 상호작용할 수 있으며,
심지어는 프로세스 간 통신(IPC)도 수행할 수 있습니다.

한 서비스는 네트워크 트랜잭션 처리, 음악을 재생 그리고 파일 I/O를 수행하거나 콘텐츠 제공자와 상호작용할 수 있으며
이 모든 것을 백그라운드에서 수행할 수 있습니다.

이런 서비스에는 세 가지 유형이 있습니다.

1. 포그라운드

포그라운드 서비스는 사용자에게 잘 보이는 작업을 수행합니다.

음악 앱이면 음악을 재생할 때 포그라운드 서비스를 사용하며 알림을 표시합니다. (유튜브, 멜론 등을 재생할 때...)

위의 이미지처럼 Notification(알림)을 통해 표시되어 있는 것을 포그라운드 서비스라고 합니다.

 

🧐 그럼 여기서 위의 멜론 Notifaction을 누르면 멜론으로 연결되는데 어떻게 연결이 되는 것일까요?

이런 Notification은 우선 사용자가 알림에 대한 설정을 모두 허용했기에 나오는 것입니다.

Notification Channel은 각각 알림을 커스텀할 수 있습니다.

애플리케이션 설정에서 추천음악 알림, 현재 재생중인 음악 알림, 메세지도착 알림 등을 허용하면 앱의 해당 알림들을 받을 수 있는 것입니다.

 

멜론 앱에서 현재 재생중인 음악 알림을 허용했기에 Notification이 위와 같이 포그라운드에서 동작할 수 있으며 이 알림을 클릭했을 때 멜론의 재생화면으로 넘어갑니다.

 

이를 알기 위해서 PendingIntent에 대해 알아야합니다.

인텐트를 포함하는 인텐트입니다. 현재 앱이 아닌 외부의 앱(Notifaction 등)이 내가 개발한 앱을 열 수 있도록 허락할 수 있는 인텐트입니다.

PendingIntent 안에는 실제 데이터를 갖고, 액티비티를 저장한 Intent를 갖고 있는 것과 같습니다.

즉, 외부(디바이스 상단 알림창) 등에서 내가 개발중인 앱을 실행하기 위해선 PendingIntent를 통해 실행할 수 있습니다.

 

 

2. 백그라운드

백그라운드 서비스는 사용자에게 직접 보이지 않는 작업을 수행합니다.

유저에게 특별히 진행상황이나 결과에 대한 내용을 전달할 필요가 없는 경우에 쓰입니다.

백그라운드 서비스는 앱이 종료되어도 동작하며 대표적으로 알람 기능이 있습니다.

이 백그라운드 서비스는 API 26 이상 부터는 포어그라운드 상태가 아닐 때 몰래 프로세스가 실행되지 못하도록 정책 변화가 생겼습니다.

왜 생겼을까요? 🧐

백그라운드 서비스는 사용자에게 인터페이스 없이 조용히 실행된다는 점에서 여러모로 악용이 되기도 했습니다.

백그라운드 프로세스에서 내부의 데이터를 보낸다던가, 데이터를 계속 가져온다던가...

원하지 않는 작업들이 계속 동작하며 이런 앱들이 많아지면 사용자의 배터리는 아주 빠르게 소모될 것입니다.

그래서 정책이 변화했고, 사용자가 앱을 실행했을 때 앱과 직접 상호작용(Foreground Service) 하고 있다면 앱은 백그라운드 서비스를 자유롭게 생성하고 실행할 수 있습니다.

백그라운드 서비스만 진행될 때도 어느정도 시간은 허용이 되지만, 유휴상태로 간주되어 Service.stopSelf() 메서드 호출처럼 백그라운드 서비스를 중지하게 됩니다.

 

앱이 Background 상태여도 작업을 하기 위해서는 Foreground Service를 사용해 알림을 발생시키도록 하는 정책인 것이죠

이제 몰래 작업을 하더라도 알림을 보내고 작업을 해야하는 것입니다 !

3. 바인드

서비스가 bind된 상태입니다. Service-Client 모델에서 서비스가 특별한 Client에 결합된 상태를 의미합니다.

Client에게 Service가 기능을 제공할 수 있도록 초기화한 것입니다.

이렇게 binding된 Service는 Server-Client 인터페이스를 제공하며 구성 요소가 Service와 상호작용하게 하며, 결과를 받을 수 있고 이와 같은 작업을 여러 프로세스에 걸쳐 IPC(프로세스 간 통신)로 수행할 수도 있습니다.

여기서 bind될 수 있는 Client의 종류가 안드로이드 컴포넌트나 IPC를 하는 프로세스일 수도 있습니다.

 

서비스의 생명 주기

startService() bindService()
onCreate() 서비스 객체 새롭게 생성될 때 호출 onCreate() 서비스 객체 새롭게 생성될 때 호출
onStartCommand() 시스템이 startService 메서드를 통해 서비스를 시작할 때 호출. onBind() 새로운 binding이 연결될 때 호출.
onDestory() 서비스 객체 파괴될 때 호출 onUnbind() 서비스와 컴포넌트의 바인딩을 해제할 때 호출
  onDestory() 서비스 객체 파괴될 때 호출