안드로이드 - Service
Android Service란 쉽게 말해서 백그라운드에서 동작하는 기능을 말하는 겁니다. 대표적인 예로는 카카오톡 앱을 실행하지 않고도 누군가 메세지를 보내면 받고 알려주는 것이 있습니다.
import android.app.Service
import android.content.Intent
import android.os.IBinder
class BasicService : Service() {
override fun onCreate() {
super.onCreate()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
}
override fun onBind(intent: Intent): IBinder {
TODO("Return the communication channel to the service.")
}
}
onDestroy() : 서비스를 더 이상 사용하지 않고 소멸할 때 호출
onCreate() : 서비스가 처음 생성되었을 때 호출
onStartCommand() : 다른 구성 요소가 서비스를 시작하도록 요청하는 경우 호출
onBind() : 다른 구성 요소가 해당 서비스에 바인딩되고자 하는 경우에 이 메서드를 호출, 바인딩을 허용하지 않으려면 null을 반환 출처:
서비스 vs 스레드 (Service, IntentService)
서비스는 그저 백그라운드에서 실행될 수 있는 구성 요소일 뿐입니다. 서비스를 사용하는 경우 기본적으로 애플리케이션의 Main Therad에서 계속 실행되므로 서비스가 해야할 작업이 많거나 중간에 Blocking 작업이 들어간다면 서비스 내에 새 스레드를 생성을 해야 합니다.
여기서 우리는 두 가지 클래스를 통해 서비스를 구현할 수 있습니다.
Service
기본적인 서비스 클래스, 서비스는 기본적으로 Main Thread를 사용하기 때문에 성능을 저하시킬 수 있으므로 새 스레드를 생성해주어야 한다.
IntentService
Service의 하위 클래스, Work Thread를 사용하여 모든 시작 요청을 한번에 하나씩 처리합니다. 만약 서비스가 여러 개의 요청을 동시에 처리하지 않아도 되는 경우 사용합니다.
출처: https://ardor-dev.tistory.com/83 [Ardor IT's Devlog:티스토리]
쓰레드 | 서비스 |
백그라운드 프로세스를 수행할 수 있는 OS 수준의 기능 | 대부분 UI 없이 백그라운드에서 오래 실행되는 작업 |
자체 쓰레드에서 실행됨 | 메인 쓰레드에서 실행됨 |
쓰레드는 경량 프로세스고 안드로이드 컴포넌트가 아니다. UI 쓰레드를 업데이트할 수 없고 이를 위한 핸들러가 필요함 |
서비스는 안드로이드 컴포넌트고, 액티비티지만 인터페이스가 없다 |
액티비티 생명주기에서 실행되며 액티비티가 파괴되면 종료 / 중지된다 | 서비스는 백그라운드에서 실행되며 액티비티 생명주기와 독립적인 자체 생명주기를 갖는다 따라서 액티비티가 파괴될 때 서비스가 명시적으로 중지되지 않는 한 서비스는 계속 실행된다 |
Service 생명주기
onStartCommand 와 onBind 로 나뉘게 된다.
onCreate()
- 서비스가 생성될 때 최초로 호출됨, 초기 설정을 수행
onStartCommand()
- startService() 로 Service가 시작될 때 호출됨. startService()를 통해 전달한 Intent를 onStartCommand() 에서 서비스가 수신하게 된다.
- 서비스는 작업이 완료되면 stopSelf()를 호출하여 스스로 중단하거나 다른 컴포넌트가 stopService() 를 호출하여 중단시킬 수 있다. (콜백 없음)
- onStartCommand()호출을 한 번이라도 받은 서비스는 lifecycle을 직접 관리 및 중단해야 한다. (이후 onBindCommand()가 호출 되었더라도)
- 시스템이 서비스를 중단하거나 소멸시키지 않음
- onStartCommand()호출을 한 번이라도 받은 서비스는 lifecycle을 직접 관리 및 중단해야 한다. (이후 onBindCommand()가 호출 되었더라도)
onBind()
- bindService() 로 클라이언트가 Service에 binding될 때 호출됨.
onUnbind()
- 모든 클라이언트들이 unbindService()를 호출해서 binding이 해지되었을 때 호출 됨.
onRebind()
- unbindService()가 호출된 이후에, 클라이언트가 bindService()를 호출하여 Service에 binding될 때 호출됨.
5. onDestory()
- Service가 해지될 때 호출 됨. 리소스 해지를 수행
onStartCommand의 경우
- 액티비티 같은 앱 컴포넌트가 startService()를 호출하면, 서비스는 실행되면(started), 그 서비스를 실행한 컴포넌트가 종료되도 할 일을 모두 마칠 때까지 서비스는 종료되지 않는다.
- 따라서 서비스가 할일을 다하여 종료시키고 싶다면, 서비스 내에서 stopSelf()를 호출하여 스스로 종료되도록 하거나, 다른 컴포넌트에서 stopService()를 호출하여 종료시켜한다.
- 액티비티 등의 앱 컴포넌트는 startService()를 호출함으로써 서비스를 실행할 수 있고, 이때 어떤 서비스를 실행할지에 대한 정보와 그 외에 서비스에 전달해야할 데이터를 담고 있는 인텐트를 인자로 넘길 수 있습니다. 그리고 서비스의 onStartCommand() 콜백 메소드에서 매개변수로 그 인텐트를 받게 됩니다.
onBind의 경우
- startService() 메소드 대신 bindService() 메소드를 통해 시작되는 서비스를 서비스 바인딩 (Service Bind 혹은 Bound Service) 라 한다.
- 마치 클라이언트-서버 와 같이 동작을 하는데 서비스가 서버 역할을 한다.
(액티비티는 서비스에게 어떠한 요청을 할 수 있고, 서비스로부터 요청에 대한 결과를 받을수 있음)
- 하나의 서비스에 다수의 액티비티 연결 가능하며, 서비스 바인딩은 연결된 액티비티가 사라지면 서비스도 소멸된다. (즉 백그라운드에서 무한히 실행되지는 않음)
- 클라이언트가 서비스와의 접속을 마치려면 unbindService() 를 호출한다.
결론: 서비스가 돌아가는 동안 지속적으로 액티비티와 커뮤니케이션 하기 위해 사용