Skip to content

Where to bind and where to unbind the bound service

Devrath edited this page Feb 24, 2024 · 7 revisions

Bind/Unbind the service in the activity

Good Approach

  • We can bind in the onCreate() and unbind in the onDestroy()
  • We can also bind in onStart() and unbind in the onStop()

Not recommended Approach

  • Binding in onResume() and unbinding in onPause()

How service connection plays the role of Bind/Unbind scenarios

Untitled Diagram drawio

  • The service connection lets us know when the service is connected and when the service is disconnected between the client and the defined service that the client is bound to.

Code

Client Code

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    private var isServiceBound = false

    /**
     * < ************************** > LifeCycle Methods < **************************>
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initOnCreate()
    }

    override fun onStart() {
        super.onStart()
        initOnStart()
    }

    override fun onResume() {
        super.onResume()
        initOnResume()
    }

    override fun onStop() {
        super.onStop()
        initOnStop()
    }

    override fun onDestroy() {
        super.onDestroy()
        initOnDestroy()
    }
    /**
     * < ************************** > LifeCycle Methods < **************************>
     */


    /**
     * < ************************** > Init Methods < *****************************>
     */
    private fun initOnCreate() {
        Log.d(APP_TAG, "Activity - onCreate is called")
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setOnClickListeners()
    }

    private fun initOnStart() {
        Log.d(APP_TAG, "Activity - onStart is called")
        bindPlayerService()
    }

    private fun initOnResume() {
        Log.d(APP_TAG, "Activity - onResume is called")
    }

    private fun initOnStop() {
        Log.d(APP_TAG, "Activity - onStop is called")
        if(isServiceBound){
            // We call un-bind only if the service is actually bound
            unBindPlayerService()
            // Set the flag to false 
            isServiceBound = false
        }
    }

    private fun initOnDestroy() {
        Log.d(APP_TAG, "Activity - onDestroy is called")
    }
    /**
     * < ************************** > Init Methods < *****************************>
     */

    /**
     * < ************************** > User Defined Methods < **********************>
     */
    private fun setOnClickListeners() {
        binding.apply {
            playAndPauseId.setOnClickListener {

            }
            stopId.setOnClickListener {

            }
        }
    }

    private fun bindPlayerService() {
        val service = Intent(this, PlayerService::class.java)
        bindService(service,serviceConn,Context.BIND_AUTO_CREATE)
    }

    private fun unBindPlayerService(){
        unbindService(serviceConn)
    }
    /**
     * < ************************** > User Defined Methods < **********************>
     */


    private val serviceConn = object : ServiceConnection {

        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            Log.d(APP_TAG, "Player Service onServiceConnected")
            isServiceBound = true
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            Log.d(APP_TAG, "Player Service onServiceDisconnected")
            isServiceBound = false
        }

    }
}

Service Code

class PlayerService : Service() {

    private lateinit var player : MediaPlayer
    private val context : Context by lazy { this }

    /**
     * < ************************** > Service Methods < **************************>
     */

    override fun onCreate() {
        initOnCreate()
    }

    override fun onBind(intent: Intent?): IBinder? {
        return initOnBind()
    }


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        initOnStartCommand()
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onUnbind(intent: Intent?): Boolean {
        initOnUnBind()
        return super.onUnbind(intent)
    }


    override fun onDestroy() {
        initOnDestroy()
        super.onDestroy()
    }
    /**
     * < ************************** > Service Methods < **************************>
     */



    /**
     * < ************************** > Init Methods < *****************************>
     */

    private fun initOnCreate() {
        Log.d(APP_TAG, "PlayerService - onCreate is called")
        // Initialize the media player
        player = MediaPlayer.create(context,R.raw.demo_music)
    }

    private fun initOnBind(): IBinder? {
        Log.d(APP_TAG, "PlayerService - onBind is called")
        return null
    }

    private fun initOnStartCommand() {
        Log.d(APP_TAG, "PlayerService - onStartCommand is called")
    }

    private fun initOnUnBind() {
        Log.d(APP_TAG, "PlayerService - onUnBind is called")
    }

    private fun initOnDestroy() {
        Log.d(APP_TAG, "PlayerService - onDestroy is called")
        player.release()
    }
    /**
     * < ************************** > Init Methods < *****************************>
     */


    /**
     * < ************************** > Client Methods < *****************************>
     */

    fun play(){
        player.start()
    }

    fun pause(){
        player.pause()
    }

    fun stop(){
        if(player.isPlaying){
            player.stop()
        }
    }

    fun togglePlayPause(){
        if(player.isPlaying){ pause() } else{ play() }
    }

    /**
     * < ************************** > Client Methods < *****************************>
     */

}
Clone this wiki locally