onUnbind() 는 boolean을 리턴하게 되어있는데, false를 리턴하면 다시 bind될 때 아무것도 불리지 않는다. 이렇게 동작하는 이유는 onBind()에서 IBinder를 한번 리턴받으면, 시스템이 이 값을 계속 재활용하기 때문이고 다시 bind를 해도 전혀 문제없이 동작하게된다.
이경우 문제가 있을 수 있는데, 예를들어 onUnbind() 에서 상태를 검사하고 stopSelf()로 서비스 종료를 하도록 해도, onBind()-onUnbind()가 두번째 binding부터는 전혀 불리지가 않아 원하는 동작을 하지 않는다.
onUnbind()에서 true를 리턴하게되면, 다시 bind될 때, onRebind()가 불리며 unbind시에는 onUnbind()가 불리게된다. 그러므로, onUnbind()에서 stopSelf()로 서비스를 종료시키려는 경우에는 true를 리턴해줘야 한다.
다음 코드는 서비스의 bind, unbind만 확인해보기 위한 코드이다.
class TimerService: LifecycleService() {
private val binder = TimerBinder()
private var timerState = TimerState.STOP
override fun onCreate() {
super.onCreate()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
return START_NOT_STICKY
}
override fun onBind(intent: Intent): IBinder? {
super.onBind(intent)
Timber.i("TimerService) onBind")
return binder
}
override fun onUnbind(intent: Intent?): Boolean {
super.onUnbind(intent)
Timber.i("TimerService) onUnbind")
if(timerState == TimerState.STOP) stopSelf()
// If return true, next binding calls 'onRebind()'.
// here, return false, next binding calls nothing. onUnbind() not called too.
// onBind() called at the first time once to get IBinder.
return true
}
override fun onRebind(intent: Intent?) {
Timber.i("TimerService) onRebind")
super.onRebind(intent)
}
override fun onDestroy() {
Timber.i("TimerService) onDestroy")
super.onDestroy()
}
// public method of service
fun start(){
Timber.i("TimerService) start()")
timerState = TimerState.RUN
}
fun pause(){
Timber.i("TimerService) Pause()")
timerState = TimerState.PAUSE
}
fun stop(){
Timber.i("TimerService) stop()")
timerState = TimerState.STOP
}
inner class TimerBinder: Binder() {
fun getService(): TimerService = this@TimerService
}
}