서비스 (Service)
- 백그라운드 작업을 위한 컴포넌트, 화면에 상관없이 장시간 동안 처리해야 하는 업무 구현시 사용
- 다른 앱이 사용자 화면을 점유하고 있더라도 앱의 프로세스가 살아서 무언가 작업을 수행해야 할 때 사용하는 컴포넌트
- 서비스의 구동방법은 startService() 와 bindService() 두 가지가 있는데 어느 함수로 실행하는지에 따라 생명주기가 다름

From. https://developer.android.com/guide/components/services
startService()
- 함수가 실행되면 onCreate() → onStartCommand() 함수가 자동으로 호출
- 이미 실행상태인 서비스를 다시 실행하면 onStartCommand() 함수만 한 번 호출된다. (싱글톤으로 동작하는 컴포넌트)
- 데이터를 주고 받으려면 intent 나 브로드캐스트 리시버를 활용해야 함
bindService()
- 함수가 실행되면 onCreate() → onBind() 함수가 호출
- 다시 실행하면 onBind() 함수만 반복 호출됨 (싱글톤)
- onBind() 함수는 다른 생명주기 함수와 다르게 반환값이 있음
- 서비스가 실행되면서 onBind() 함수에서 반환한 객체가 서비스를 실행한 곳에 바인딩
- bindService() 함수로 실행된 서비스는 자신에게 바인드된 컴포넌트가 없으면 자동 종료
- 여러 액티비티가 bindService() 함수로 서비스를 이용하고 있다면, 하나의 액티비티가 종료되거나 unbindService() 함수를 호출하더라도 계속 실행됨
START_STICKY
- Service가 강제 종료되었을 경우 시스템이 다시 Service를 재시작 시켜 주지만 intent 값을 null로 초기화 시켜서 재시작.
- Service 실행시 startService(Intent service) 메서드를 호출 하는데 onStartCommand(Intent intent, int flags, int startId) 메서드에 intent로 value를 넘겨 줄 수 있음.
- 기존에 intent에 value값이 설정이 되있다고 하더라도 Service 재시작시 intent 값이 null로 초기화 되서 재시작
START_NOT_STICKY
- 강제로 종료 된 Service가 재시작 하지 않음. 시스템에 의해 강제 종료되어도 괜찮은 작업을 진행 할 때 사용
START_REDELIVER_INTENT
- START_STICKY와 마찬가지로 Service가 종료 되었을 경우 시스템이 다시 Service를 재시작 시켜 주지만 intent 값을 그대로 유지.
- startService() 메서드 호출시 Intent value값을 사용한 경우라면 해당 Flag를 사용해서 리턴값을 설정
데이터 공유 (startService())
- startService() 함수로 실행된 서비스의 데이터 공유 방법
- 서비스나 액티비티 내부에 브로드캐스트 리시버를 정의 하고, 데이터 전달이 필요할 때 실행하여 브로드캐스트 인텐트에 Extra 데이터로 전달
- 액티비티에서 재생이나 정지 등의 정보를 인텐트의 Extra 에 담아 인텐트 발생, 그 인텐트로 서비스 내부에 구현된 브로드캐스트 리시버 실행, 서비스쪽에서 받은 브로드캐스트 리시버에서 Extra 데이터를 추출하여 사용
- 서비스에서 Extra 데이터를 담은 인텐트를 발생시켜 액티비티 내부에 구현한 브로드캐스트 리시버를 실행, 액티비티의 브로드캐스트 리시버가 실행되면서 넘어온 데이터를 획득하여 액티비티에서 사용
데이터 공유 (bindService())
- 서비스가 실행되면서 서비스에서 준비한 객체가 액티비티로 바인딩 되는 구조. 바인딩 객체의 함수를 호출하여 함수의 매개변수와 반환값으로 데이터를 주고받는 구조
- AIDL 에서 많이 사용되는 방식
AIDL (Android Interface Definition Language)
- 두 앱의 프로세스가 실행된 상태에서 발생하는 데이터를 프로세스 간의 통신을 통해 주고받기 위한 기술
- 직접 코드를 작성하지 않고 외부 앱의 함수 호출만으로 구현가능하기 때문에 개발이 쉬워짐.
- bindService() 함수로 서비스 컴포넌트를 실행하여 객체를 공유하고, 공유된 객체의 함수를 호출하면서 프로세스 간의 통신을 수행
- 작동 순서
- 서버 프로세스쪽 에서 확장자가 aidl 인 파일을 만듦. aidl 을 구현하여 실제 업무 로직을 가지는 객체를 서버 프로세스에서 서비스 컴포넌트로 준비. 클라이언트 프로세스 쪽에서도 공유되어야 함
인텐트 서비스 (Intent Service)
- 일반 서비스와 비슷한 생명주기를 가지고 있지만 onHandleIntent() 라는 함수의 수행이 끝나면 자동으로 종료된다.
- 싱글톤으로써 onCreate() 는 한번만 호출되고 onStartCommand() 는 여러번 호출되며, 첫번째 IntentService 가 끝나기 전에는 다른 IntentService 는 대기상태가 된다.
시스템 서비스 (System Service)
- 시스템에서 제공하는 특수 목적의 서비스
- ActivityManager, PackageManager, LayoutInflater, NotificationManager 등이 있음
- ActivityManager 로 화면에 나타나고 있는 최상위 액티비티를 판단할 수 있음
- PackageManager 로 사용자의 스마트폰에 설지된 앱 목록, 인텐트에 반응할 컴포넌트 정보 등을 구하는 목적으로 사용된다,
백그라운드 서비스 제한
- Android Oreo 버전부터 백그라운드 서비스 실행 제한이 생김
- 앱이 포그라운드에 있더라도 암시적 인텐트로 서비스를 구동하는 것은 API Level 26 부터 불가능
- 백그라운드 상황에서 앱의 서비스를 정상적으로 구동하려면 startForegroundSerivce() 함수를 사용하여 서비스 인텐트를 발생시키면 됨 (서비스를 포그라운드 서비스로 만드는 기법)