
서비스란
= 보이지않게 돌아가는 4대 컴포넌트(액티비티, 서비스, 브로드캐스트 리시버, 컨텐츠 프로바이더) 중 하나.
androidmanifest.xml에 선언해주면 된다.
<service android:name=".ConnectionService"/>
: application 내에 선언해주면 되며, android:enable의 경우 service를 인스턴스화 할지 여부를 나타낸다. 기본값은 true로 고정.
: android:exported의 경우 어플리케이션의 구성요소가 서비스와 상호작용할 수 있는지 여부를 나타낸다.

: 간단한 서비스의 생명주기.
: startservice는 독립실행, bindservice는 종속 실행이란 점
왜 포그라운드 일까?
ex) 사운드클라우드.
= 다른 앱을 실행하고 있어도 그 위에 오디오 트랙을 재생시킬 수 있다.
: startService()로 호출되고, onStartCommand로 실행된다.
: stopself, stopService가 호출되지 않는 이상 계속 실행된다.
프로세스의 우선순위가 가장 높은 작업.
프로세스의 우선순위가 낮은 편인 작업.
서비스의 우선순위는 명령어로 소멸되는 것이 아니라, 안드로이드 시스템이 서비스를 소멸시키는 경우, 즉 리소스가 부족해서 강제로 소멸시키는 경우 뿐이다.
포그라운드 서비스 > 바인드 > 백그라운드 서비스 순서로 중요도가 높다.
: bindService와 StartService()는 모두 서비스를 실행시킬 때 사용되는 함수이다. 별개인 것처럼 서술했지만, 동시에 쓰여도 상관없다.
startService로 실행된 포그라운드 서비스에 bindService로 구성요소를 service에 bind해서 사용하더라도 상관 없다.
단, 이 경우에는 모든 구성요소가 unbind 되더라도 서비스가 소멸되지 않는다.
백그라운드 서비스를 실행시키는 startService()는 실행될 때마다 서비스를 생성한다.
하지만 바인드 서비스를 실행하거나 구성요소를 bind하는데 사용되는 bindService()는 항상 서비스를 생성하지는 않고 서비스가 꺼져있을 때만 실행해준다.
서비스는 기본적으로 main thread에서 구동된다.
따라서 서비스 내에서 어떤 작업을 수행하고 싶다면 새로운 thread를 생성해 그 안에서 수행하도록 해야한다.
val connection : ServiceConnection = object : ServiceConnection{
override fun onServiceConnected(name: ComponentName?, service: IBinder?){}
override fun onServiceDisconnected(name: ComponentName?){}
}
val intent = Intent(this, MyService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
-서비스 종료
unbindService(connection)
: ServiceConnection 인터페이스를 구현한 객체를 준비한다.
: onServiceConnected()는 bindService() 함수로 서비스를 구동할 때 자동으로 호출된다.
: onServiceDisconnected()는 unbindSerevice() 함수로 자동으로 호출되지 않고, 시스템에 의해서 메모리 문제 등으로 종료될 경우에 호출된다.
val intent = Intent(this, MyService::class.java)
startService(intent)
val intent = Intent("ACTION_OUTER_SERVICE")
intent.setPackage("com.example.test_outter")
startService(intent)
val intent = Intent(this, MyService::class.java)
stopService(intent)
: startService() 함수로 서비스를 실행하려면 해당 서비스를 인텐트에 담아서 매갭변수로 전달해야 한다.
: 외부 앱의 서비스라면 암싯적 인텐트로 실행해야 하므로 setPackage() 함수를 이용해 앱의 패키지명을 명시해야한다.
: 서비스를 종료하려면 stopService() 함수로 인텐트를 전달한다.
재시작을 위해서는 onStartCommand의 return 값에 의해서 정의가 된다.
START_STICKY : 시스템이 서비스를 중단하면 다시 재시작한다.
START_NOT_STICKY : 시스템이 서비스를 중단하면 재시작하지 않는다.
START_REDELIVER_INTNET : 서비스 중단 후 서비스 재생성. 마지막 인텐트로 onStartCommand를 호출.
onBind
: 다른 구성요소와 서비스에 바인딩되려는 경우에 호출한다.
서비스가 죽어있다면 바인드 서비스를 실행하도록 요청하는 메소드라고 볼 수 있다.
바인딩을 실행하려는 곳(ex. Activity)에서 bindService()를 써서 호출된다.
구성요소와 서비스가 소통을 할 때 사용되는 IBinder를 반환한다. 바인딩을 허용하지 않을 때는 null을 반환한다.
onCreate
: onStartCommand() 또는 onBind()를 호출하기 전에 호출한다.
일회성으로 실행되며, 서비스가 이미 실행 중이면 onCreate()는 호출되지 않는다.
onDestroy
: 서비스를 소멸시킬 때 호출한다. 각종 리소스를 정리하기 위해 구현해야 한다.
: 백그라운드 작업을 위한 애플리케이션 구성요소, activity는 사용자에게 보이는 화면이고, service는 뒤에서 수행한다.
: 예를 들어 음악실행, 파일입출력, 네트워크 트랜젝션, 전화앱 키지 않아도 전화를 받을 수 있는 것이 service가 수행하는 기능이다.
startService() : activity에서 startservice()를 써서 서비스 호출 시 onStartCommand()가 호출되고 중단 전까진 실행 중인 상태. stopSelf()로 스스로 중단하거나 다른 프로세스에서 stopService()로 중단.
bindService() : 한 activity에서 이를 호출 시 해당 서비스는 해당 요소가 바인딩된 경우에만 실행. 서비스의 모든 바인딩이 해제되면 시스템에 의해 소멸.
수명 주기
: 서비스가 startService()를 사용하여 시작되면 stopService()또는 stopSelf() 메서드를 사용하여 중지될 때까지 백그라운드에서 계속 실행된다.
: bindService()를 사용하여 바인딩되면 클라이언트가 바인딩되어 있는 동안에만 서비스가 활성화된다. 모든 클라이언트가 서비스에서 바인딩 해제되면 시스템은 서비스의 onUnbind() 메서드를 호출하고 서비스는 startService()를 사용하여 시작되지 않는 한 파괴된다.
통신
: startService()는 클라이언트와 서비스 간의 단방향 통신이다. 클라이언트는 서비스를 시작하고 서비스는 독립적으로 실행된다. 클라이언트는 인텐트 엑스트라를 사용하여 서비스에 데이터를 전달할 수 있지만, 클라이언트와 서비스 간에는 직접적인 통신이 없다.
: bindService()는 클라이언트와 서비스 간의 양방향 통신을 허용한다. 클라이언트는 ServiceConnection 개체를 사용하여 서비스에 메시지를 보낼 수 있고 서비스는 Binder 개체를 사용하여 클라이언트에 다시 메시지를 보낼 수 있다.
반환 값
: startService()는 어떤 값도 반환하지 않는다. 클라이언트는 서비스를 시작하고 서비스는 독립적으로 실행된다.
: bindService()는 바인딩이 성공했는지 여부를 나타내는 부울 값을 반환한다.
접속 개수
: startService()는 여러 클라이언트에서 동시에 사용할 수 있으며 서비스는 모든 클라이언트가 중지할 때까지 백그라운드에서 계속 실행된다.
: bindService()는 한 번에 하나의 클라이언트에서만 사용할 수 있다. 이미 다른 클라이언트에 바인딩된 상태에서 다른 클라이언트각 서비스에 바인딩을 시도하면 시스템에서 RuntimeException이 발생한다.
➡️ 요약하자면, startService()는 백그라운드에서 장기 실행 작업을 수행하려는 경우에 유용하고 bindService()는 클라이언트와 서비스 간에 직접 통신 채널을 설정하려는 경우에 유용하다.