오늘은 안드로이드 컴포넌트 중 서비스를 공부했다.
서비스는 오래걸리는 작업을 백그라운드에서 처리할 수 있게 해주는 컴포넌트다.
class MyService : Service() {
override fun onBind(intent: Intent): IBinder? {
return null
}
}
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"></service>
val intent = Intent(this, MyService::class.java)
startService(intent)
stopService(intent) // 실행 종료 함수
// 외부 앱 실행시(단, 백그라운드 상태면 실행 불가)
val intent = Intent("ACTION_OUTER_SERVICE")
intent.setPackage("com.example.test_outer")
startService(intent)
// ServiceConnection 객체 생성
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)
onCreate()가 서비스 객체 생성시 한번만 호출
onStartCommand()는 startService() 함수가 실행될 때마다 반복 호출
stopService() 함수로 서비스가 종료되면 바로 전에 onDestory() 함수가 호출
bindService() 함수에서 서비스 객체를 생성하면 onCreate -> onBind() 함수가 호출
다시 bindService() 함수로 실행하면 onBind() 함수만 다시 호출
unbindService() 함수로 서비스를 종료하면 onUnbind() -> onDestory() 함수까지 실행
반면, 액티비티와 서비스 객체가 상호작용이 필요하다면 bindService()로 객체 바인딩을 하는 것이 유용하다.
서비스 코드의 onBind()함수의 반환 타입은 IBinder 인터페이스다. 이를 구현한 객체를 생성해 반환으로 넘긴다.
class MyService : Service() {
override fun onBind(intent: Intent): IBinder {
return MyBinder()
}
}
class MyBinder: Binder(){
fun funA(arg: Int){
}
fun funB(arg: Int): Int{
return arg*arg
}
}
val connection: ServiceConnection = object : ServiceConnection{
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val serviceBinder = service as MyService.MyBinder
}
override fun onServiceDisconnected(name: ComponentName?) { }
}
앞의 IBinder를 구현한 객체를 바인딩하는 방법과 달리, API에서 제공하는 Messenger 객체를 바인딩하는 방법도 있다.
메신저 바인딩은 IPC, 프로세스간 통신에도 사용된다. 외부 앱과 연동해 통신이 가능하다.
handleMessage() 함수는 외부에서 서비스에 데이터를 전달할 때 자동으로 호출된다. 이때 외부에서 전달한 데이터는 Message 타입이다.
Message의 what값으로는 어떤 성격의 데이터인지를 구분하며 obj 속성으로는 전달된 데이터를 가져온다.
onBind() 함수의 반환값으로 Messenger 객체를 생성하면서 생성자 매개변수로 Handler를 구현한 객체를 지정한다.
액티비티 코드에선 onService Connected() 함수의 매개변수로 넘어온 객체를 Messenger의 생성자 매개변수에 지정한다. 서비스 실행 후 데이터를 전달하고 싶을 땐 Messenger.send() 함수를 사용한다.
외부 앱의 서비스를 Messenger 방식으로 bindService() 함수를 이용해 사용하려면 매니페스트에 <intent-filter>를 선언해야 한다.