[연재] 알면 편해지는 안드로이드 코틀린 생명주기 ②

액티비티와 서비스는 생명 주기 흐름을 따라 생성되고 동작하고 종료됩니다. 따라서 생명주기를 알아야 합니다. 이번 연재에서는 액티비티와 서비스 각각의 생명 주기를 2회에 걸쳐 소개합니다.

① 액티비티 생명 주기
② 서비스 생명 주기

—–

② 서비스 생명 주기

서비스는 백그라운드에서 꺼지지 않고 작업을 수행하는 안드로이드 4대 구성요소 중 하나입니다. 사용자가 서비스를 실행하면, 시스템에게 “이건 서비스라는 건데, 사용자와 인터랙션을 하지는 않지만 오랫동안 실행되어야 해. 누군가가 멈추라고 하기까지는 멈추지 말아줘”라고 알려줍니다. 서비스는 독립된 구성요소이기 때문에 독립된 생명 주기를 가집니다. 액티비티가 소멸되더라도 서비스는 독립된 상태로 실행이 되고 있어서 다시 액티비티를 생성하여 해당 서비스와 소통할 수도 있습니다. 서비스를 앱에서 사용하려면 AndroidManifest.xml에 직접 추가해주어야 합니다.
우리가 자주 쓰는 음악 앱을 한번 실행해보세요. 음악이 재생되고 있을 때 앱을 꺼버리더라도 음악은 계속 재생될 겁니다. 다시 앱을 실행하면 재생되고 있는 음악의 정보를 바로 볼 수 있습니다. 이러한 일이 어떻게 일어날 수 있을까요? 서비스 덕분입니다.

서비스 유형은 크게 세 가지로 나눌 수가 있습니다.

  1. 시작된 서비스
  2. 바인드된 서비스
  3. 시작되고 바인드된 서비스

1. 시작된 서비스

서비스를 시작하려면 startService( ) 함수를 액티비티나 다른 서비스에서 실행해야 합니다. startService( )를 호출하면 서비스가 시작되고 서비스 내의 콜백 메서드인 onCreate( )와 onStartCommand( )가 차례로 호출이 되어 시작된 상태가 됩니다. 한 번 시작된 상태가 된 서비스는 stopSelf( ) 함수로 알아서 중지하거나, 다른 구성요소가 stopService( )를 호출하여 서비스를 명백하게 종료시키기 전까지는 계속 실행 중인 상태로 존재합니다. 앞의 두 가지 방법 중의 하나로 서비스를 종료하면 onDestroy( ) 함수가 호출되어 서비스가 완전히 종료됩니다. 또한 서비스는 아무리 많은 구성요소에서 startService( )를 호출하더라도 서비스 객체는 하나만 생성되며 onCreate( ) 함수 역시 서비스를 만들 때 처음에만 호출이 됩니다. 그래서 서비스
에서 딱 한 번만 수행되어야 하는 작업은 onCreate( ) 함수를 이용합니다.

 

 

2. 바인드된 서비스

바인드된 서비스는 무엇을 뜻할까요? 바인드는 ‘묶다’라는 뜻입니다. 뭔가 흩어진 요소를 연결되게끔 묶다는 뜻이지요. 바인드가 된 서비스는 다른 구성요소와 연결이 가능합니다. 예를 들면 액티비티가 서비스와 바인딩이 되었다면 액티비티는 서비스에 정의된 함수를 사용할 수 있고, 서비스에 요청을 보내 응답을 받을 수 있습니다. 다른 앱의 구성요소가 서비스에 접근할 수 있도록 만들 수도 있습니다. 그러므로 마치 서버(서비스)와 클라이언트(다른 구성요소) 관계를 이룬다고 할
수 있습니다. 바인드된 서비스는 기본적으로 다른 구성요소들에 바인드된 동안에만 실행됩니다. 계속 백그라운드에서 실행되는 것은 아닙니다.

언제 바인드된 서비스를 이용할까요? 예를 들면 음악 앱에서 서비스를 실행한 후 음악을 재생하면 앱에서 나가더라도 계속 재생이 됩니다. 그리고 다시 앱을 실행하면 바로 액티비티가 서비스와 바인드가 되고 재생을 컨트롤할 수 있게 되는 것이지요.

다음 코드는 액티비티에서 바인드된 서비스를 시작합니다.

액티비티에서 bindService( ) 함수를 호출할 때 인텐트 객체, 서비스 연결 관련 정보를 받을 수 있는 Service Connection 구현 객체와 Context.BIND_AUTO_CREATE를 인수로 줍니다. 안드로이드 시스템에 의해 구성요소가 서비스와 연결되면 해당 구현 객체의 onServiceConnected( ) 함수가 호출되는데, 여기에서 서비스와 통신을 가능케 하는 IBinder 객체를 전달받습니다. BIND_AUTO_CREATE는 bindService( ) 함수를 실행했을 때 만약 해당 서비스가 없으면 서비스의 onCreate( ) 콜백 함수를 실행시켜 서비스를 생성하라는 의미입니다.

그렇다면 바인드된 서비스의 생명 주기를 살펴봅시다. 방금 살펴본 bindService( ) 함수를 액티비티와 같은 구성요소에서 호출합니다. 만약 서비스가 생성되어 있지 않다면 onCreate( ) 함수를 실행해줍니다. onBind( )가 호출되었을 때는 서비스는 IBinder 인터페이스 구현 객체를 bindService( )를 호출한 구성요소에 전달합니다. 해당 구성요소가 IBinder를 받고 나서부터는 이것을 통해 서비스와 상호작용을 할 수 있게 되는 겁니다. 모든 연결된 구성요소들이 unBindService( )를 호출하여 서비스와의 연결을 모두 끊게 되면 onUnbind( )가 실행되고 이어서 5 onDestroy( )가 호출되면서 완전히 서비스가 종료됩니다.


이쯤되면 ‘시작된 서비스’와 ‘바인드된 서비스’가 뭐가 다른지 헷갈릴 수 있습니다. 차이점은 아래와 같습니다.

  • 시작된 서비스는 다른 구성요소와의 연결고리가 없습니다. 단순히 startService( ) 함수를 실행해 서비스를 시작하고, stopService( )로 서비스를 멈춥니다. 예를 들면 크기가 큰 동영상을 다운받는 경우를 생각해봅시다. 서비스를 시작하고 다운로드가 종료되면 서비스에서 stopSelf( )를 호출해 서비스를 종료시키면 됩니다.
  • 바인드된 서비스는 IBinder라는 인터페이스를 매개로 다른 구성요소와 소통할 수 있습니다. bindService( )는 서비스와 연결된 다른 구성요소들이 모두 unbindService( )를 호출하여 연결을 끊게 되면 서비스가 종료됩니다. 그러므로 계속 살아있어야 하는 태스크에는 부적절합니다.

홍정아
블록체인 개발 회사, 앱 개발 스타트업 CTO를 거쳐 현재는 테크 스타트업의 대표입니다. 유튜브에서 ‘코틀린 강의’를 검색하면 제일 상단에서 Code with Joyce 채널에 2020년 연재한 코틀린 강의를 만날 수 있습니다.

Leave a Reply

©2020 GoldenRabbit. All rights reserved.
상호명 : 골든래빗 주식회사
(04051) 서울특별시 마포구 양화로 186, 5층 512호, 514호 (동교동, LC타워)
TEL : 0505-398-0505 / FAX : 0505-537-0505
대표이사 : 최현우
사업자등록번호 : 475-87-01581
통신판매업신고 : 2023-서울마포-2391호
master@goldenrabbit.co.kr
개인정보처리방침
배송/반품/환불/교환 안내