Services in Android

Overview

A service is an application component that can perform long-running tasks in the background. It does not provide a user interface. Once started, a service might continue running for some time, even after the user switches to another application. Additionally, a service can bind with another application component.

There are three type of services
  • Unbound Service
  • Bound Service
  • Intent Service

Thread vs Services

  • Thread run on its own thread. Service runs on main thread.
  • Thread is a lightweight process. It's not an application component. Service is an application component. It is also an activity but with no user interface.
  • Threads run in the lifecycle of an activity. If an activity is destroyed then it's threads are either killed or destroyed. Service runs in the background even if the activity is destroyed unless and until the service is stopped. Service has it's own lifecycle.

Steps to follow

  • Create a class and extend it with Service class. 
  • If you are not creating a bound service then modify the IBinder type to return a null value.
 override fun onBind(intent : Intent) : IBinder?
{
return null;
}
  • Override other methods of the lifecycle of Service in the class. The below Service runs on main thread that's why it will hang the application before it loads until the service is stopped. 
 class LogService : Service()
{
companion object
{
const val TAG = "LogService"
}

override fun onCreate()
{
printLogs("onCreate")
super.onCreate()
}

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

override fun onStartCommand(intent : Intent? , flags : Int , startId : Int) : Int
{
printLogs("onStartCommand")
for (i in 1 .. 10)
{
printLogs("Something is working in background...")
Thread.sleep(1000)
}
stopSelf()
return super.onStartCommand(intent , flags , startId)
}

override fun onDestroy()
{
printLogs("onDestroy")
super.onDestroy()
}

private fun printLogs(message : String)
{
Log.d(TAG , message)
}
}
  • In the below code we have created this service on a new thread, thus the service runs in the background without causing a significant impact on the application. 
 class LogService : Service()
{
companion object
{
const val TAG = "LogService"
}

override fun onCreate()
{
printLogs("onCreate")
super.onCreate()
}

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

override fun onStartCommand(intent : Intent? , flags : Int , startId : Int) : Int
{
printLogs("onStartCommand")
val runnable = Runnable {
for (i in 1 .. 10)
{
printLogs("Something is running the background...")
Thread.sleep(1000)
}
stopSelf()
}
val thread = Thread(runnable)
thread.start()
return super.onStartCommand(intent , flags , startId)
}

override fun onDestroy()
{
printLogs("onDestroy")
super.onDestroy()
}

private fun printLogs(message : String)
{
Log.d(TAG , message)
}
}
  • Call the service in MainActivity.
 class MainActivity : AppCompatActivity()
{
override fun onCreate(savedInstanceState : Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Intent(this , LogService::class.java).apply {
startService(this)
}
}
}

Do's and Dont's

  1. Service usually runs on main thread. So if you are using a service then please consider running the service on a thread otherwise it will hang your application until the service gets stopped either by itself or through any other method like stopService(), stopItself() or unbind().
  2. If you won't call any stop service methods like stopService(), stopItself() or unbind() then the service will keep running on background. In this case the onDestroy() method of service lifecycle won't be called.
  3. If you are running a service on a thread make sure to use stop service methods like stopService(), stopItself() or unbind() inside the Runnable object.

References





Comments

Popular posts from this blog

SSLSocketFactory in Android

Architecture Components in Android

DataBinding in Android