DEV Community

Cover image for Quick example of creating a custom Kotlin coroutine and scoping it to a Android service.
Tristan Elliott
Tristan Elliott

Posted on

Quick example of creating a custom Kotlin coroutine and scoping it to a Android service.

Resources

My app on the Google play store

My app's GitHub code

The code

  • Here is a short example of how to create a custom coroutine and scope it to the lifecycle of a Android service
class BackgroundStreamService: Service() {

    private var job: Job? = null

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

   private fun startTimer( ) {

        // Define CoroutineScope tied to the service lifecycle
        job = CoroutineScope(Dispatchers.IO + CoroutineName("ServiceTimer")).launch {
            //coroutine code
        }
    }


override fun onDestroy() {
        super.onDestroy()

        job?.cancel()

    }

}

Enter fullscreen mode Exit fullscreen mode

lanuch{}

  • launch{} is called a coroutine builder, meaning that it literally builds the coroutine for us. Everything inside of the brackets is considered the actual coroutine. Also, among the coroutine builders it is fire and forget so we should not expect it to return a value. it operates entirely on side effects

Dispatchers.IO

  • Every coroutine is tied to a particular dispatcher and that dispatcher is tied to a thread pool. Dispatchers.IO is a dispatcher designed specifically work that should be done off the main thread.

Scope

  • In coroutines the scope controls all of the coroutines inside of it. If a scope is cancelled, then all of the coroutines inside of that scope are also cancelled

Creating a custom scope

  • Your first thought is probably why? or what purpose does this solve?. For my own code, it is a practical example of creating a foreground service that shows a clock notification to the user and constantly updates it.

  • Creating the actual scope looks like this:

 job =CoroutineScope(Dispatchers.IO + CoroutineName("ServiceTimer")).launch {
            //coroutine code
        }

Enter fullscreen mode Exit fullscreen mode
  • As you can see, we create a custom scope, define its dispatcher, give it a name(for easier logging and debugging) and assign it to the job. job actually represents the coroutine its self.

Cancelation

  • To prevent memory leaks, we can go ahead and call cancel() inside of the onDestroy() method to destroy the coroutine from memory

Conclusion

  • Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on Twitter.

Top comments (0)