서비스(Service) 알아보기
안녕하세요
안드로이드 개발자가 되기 위해 노력하는 서경원입니다.
서비스에 대해 공부한 내용을 정리하고 설명해드리려고 합니다.
이해가 안되는 내용이나 제가 잘못 적은 부분이 있다면 꼭 댓글 남겨주세요.
안드로이드에서 중요한 서비스에 대해 설명하려 합니다.
서비스는 안드로이드 4대 컴포넌트 중 하나 입니다.
백그라운드에서 오래 실행되는 작업을 수행할 수 있는 애플리케이션 구성 요소로 백그라운드에서 러닝 트래킹을 실행하거나 음악을 재생할 때 사용합니다.
서비스는 메인 쓰레드에서 동작하기 때문에 ANR 발생을 조심하여 사용해야합니다.
서비스는 startService() 와 bindService() 로 2가지 방법으로 실행할 수 있습니다.
startService()
startService()로 Service를 실행시키면 onCreate()가 실행된 후 onStartCommand()가 호출됩니다.
onStartCommand() 메서드에서 받은 intent로 service의 동작을 제어할 수 있습니다.
bindService()
서비스와 상호작용을 하기 위해 사용됩니다. bindService 실행 시에는 onStartCommand() 메서드가 실행되지 않고 onBind() 메서드가 호출됩니다. bindService를 호출한 컴포넌트와 바인딩이 되어 Service와 상호작용을 할 수 있습니다. (Service의 변수에 접근하는 등의 상호작용을 할 수 있습니다.)
시작한 서비스와 바인딩 할 수 있습니다. 서비스가 시작되고 바인딩을 하게 되면 바인딩을 해제해도 서비스가 소멸되지 않기 때문에 서비스를 확실히 중단해야합니다.
bindService()를 실행할 때 flag를 설정할 수 있습니다.
BIND_AUTO_CREATE
: 서비스가 바인딩된 컴포넌트(액티비티 등)가 활성 상태인 경우, 서비스가 아직 실행 중이지 않으면 시스템이 서비스를 자동으로 시작합니다. 이 플래그를 사용하면 서비스를 명시적으로 시작할 필요가 없습니다.BIND_AUTO_CREATE
플래그를 사용하여 서비스를 바인딩할 때, 반드시unbindService()
를 호출하여 클라이언트가 서비스에 대한 바인딩을 해제해야 합니다. 그렇지 않으면 메모리 누수 등의 문제가 발생할 수 있습니다.BIND_DEBUG_UNBIND
: 서비스의 디버깅을 지원하기 위한 옵션으로, 서비스와의 연결이 해제될 때 디버깅 정보를 출력합니다.BIND_NOT_FOREGROUND
: 서비스가 포그라운드 서비스가 아니더라도,startForeground()
가 호출된 경우에도 포그라운드 서비스로 간주하지 않도록 합니다.BIND_IMPORTANT
: 서비스의 우선순위를 높여 시스템이 해당 서비스를 중요한 컴포넌트로 간주하도록 합니다.
서비스의 유형
서비스에는 세 가지 유형이 있습니다.
포그라운드 서비스
Notification으로 보이는 서비스라고 생각하시면 됩니다. 사용자가 앱을 종료하더라도 계속해서 백그라운드에서 실행됩니다.
백그라운드 서비스
사용자에게 보이지 않는 작업을 수행합니다. 보이지 않는 작업이기 때문에 동작에 제한에 있습니다. API 26 이상에서는 앱이 포그라운드에 있지 않을 때 사용이 제한됩니다.
바인드 서비스
bindService()를 호출하여 바인딩된 서비스입니다. 서비스와 상호작용 하기 위해서 사용되는 서비스 입니다. 앱이 서비스에 연결되어 있을 때만 유지됩니다. 바인드 서비스를 사용할 때는 클라이언트 앱의 연결 상태를 관리해주어야 합니다.
서비스의 예기치 못한 종료
서비스도 메모리 부족으로 예기치 못한 종료 상황이 있을 수 있습니다. (다만, 포그라운드 서비스는 메모리 부족에서도 시스템이 중단할 후보로 정하지 않는다고 합니다.)
메모리 부족으로 종료되는 경우에는 onDestroy() 메서드도 호출되지 않습니다.
onStartCommand()에서 아래 flag를 return 시켜준다면 해당 작업을 수행할 수 있습니다.
START_STICKY
Service가 강제 종료되었을 경우 시스템이 다시 Service를 재시작 시켜 주지만 intent 값을 null로 초기화 시켜서 재시작 합니다. Service 재시작시 intent 값이 null로 초기화 되서 재시작 됩니다.
START_NOT_STICKY
이 Flag를 리턴해 주시면, 강제로 종료 된 Service가 재시작 하지 않습니다. 시스템에 의해 강제 종료되어도 괸찮은 작업을 진행 할 때 사용해 주시면 됩니다.
START_REDELIVER_INTENT
START_STICKY와 마찬가지로 Service가 종료 되었을 경우 시스템이 다시 Service를 재시작 시켜 주지만 intent 값을 그대로 유지 시켜 줍니다. 따라서 종료된 Service가 아직 처리하지 못한 작업이나 요청이 있었다면, 해당 작업을 재개하고 이전 상태를 복원할 수 있습니다.
이 모드는 일부 작업을 수행하는 동안 Service가 강제로 종료될 수 있는 경우에 유용합니다. 예를 들어, 네트워크 요청을 처리하고 있던 Service가 네트워크 연결이 끊겨서 종료되었을 때, 다시 시작된 Service는 이전에 진행 중이던 네트워크 요청을 다시 시작할 수 있습니다.
'Android' 카테고리의 다른 글
Compose에서 Naver Map 적용하기 - 1) 위치 가져오기, 카메라 이동 (0) | 2024.02.25 |
---|---|
편하게 사용하고자 만든 Extensions (0) | 2023.10.04 |
Paging, 안드로이드에 맞는 커서 페이징 방식으로 구현하기 (0) | 2023.06.06 |
CoroutineDispatcher.Main.immediate 알아보기 (0) | 2023.05.31 |
Clean Architecture 궁금했던 점 살펴보기 (0) | 2023.05.31 |