Definition:
- A service is an element of an application that has the ability to carry out ongoing tasks in the background.
- There is no user interface offered.
- Even if the user goes to another programme after starting a service, the service may continue to operate for a while.
- Furthermore, a component can communicate with a service by binding to it and even carry out interprocess communication (IPC).
- For instance, a service can operate in the background while handling network transactions, playing music, doing file I/O, or interacting with content providers.
Caution:
- Unless you indicate otherwise, a service does not generate its own thread or operate in a separate process; rather, it runs in the main thread of the process that hosts it.
- In order to prevent Application Not Responding (ANR) issues, you should perform any blocking actions on a different thread inside the service.
Types of Services
These are the three different types of services:
- Foreground
- A foreground service carries out a task that the user can see.
- To play an audio track, for instance, an audio app might use a foreground service.
- A Notification must be displayed by foreground services.
- Even when the user isn't engaging with the app, foreground services keep operating.
- Use of a foreground service necessitates the presentation of a notice to make consumers aware that the service is active.
- Until the service is terminated or moved out of the forefront, this message cannot be ignored.
- Background
- An action is carried out by a background service without the user being aware of it.
- A background service would often be utilised, for instance, if a programme needed to access a service to compress its storage.
- Bound
- When an application component ties to a service by using bindService, the service is bound ().
- A bound service provides a client-server interface so that components may communicate with it, submit requests, get results, and even do so across processes via interprocess communication (IPC).
- A bound service only functions when it is bound to another application component.
- The service can have several components connect to it simultaneously, but when they all unbind, the service is terminated.
Note: It's simply a matter of whether you implement a couple of callback methods: onStartCommand() to allow components to start it and onBind() to allow binding.
Regardless of whether your service is started, bound, or both, any application component can use the service in the same way that any component can use an activity—by starting it with an Intent.
However, you can declare the service as private in the manifest file and block access from other applications.
A service and a thread
- A service is basically a component that can continue to function in the background even when a user is not interacting with it, therefore you should only develop one if you actually need one.
- Instead, you should start a separate thread in the context of another application component if you need to do something other than what is now happening in your main thread but only while the user is utilising your application.
- A thread could be created in onCreate(), started in onStart(), and stopped in onStop(), for instance, if you wish to play music only while your activity is active ().
- Also consider using thread pools and executors from the java.util.concurrent package or Kotlin coroutines instead of the traditional Thread class.
Remember: if you do use a service, it still runs in your application's main thread by default, so you should still create a new thread within the service if it performs intensive or blocking operations.
The basics or Life Cycle of Services
- To create a service, you must create a subclass of Service or use one of its existing subclasses.
- In your implementation, you must override some callback methods that handle key aspects of the service lifecycle and provide a mechanism that allows the components to bind to the service, if appropriate.
These are the most important callback methods that you should override:
- onCreate()
- The system invokes this method to perform one-time setup procedures when the service is initially created (before it calls either onStartCommand() or onBind()).
- If the service is already running, this method is not called.
- onStartCommand()
- The system invokes this method by calling startService() when another component (such as an activity) requests that the service be started.
- When this method executes, the service is started and can run in the background indefinitely.
- If you implement this, it is your responsibility to stop the service when its work is complete by calling stopSelf() or stopService().
- If you only want to provide binding, you don't need to implement this method.
- Note: If a component starts the service by calling startService() (which results in a call to onStartCommand()), the service continues to run until it stops itself with stopSelf() or another component stops it by calling stopService().
- onBind()
- The system invokes this method by calling bindService() when another component wants to bind with the service (such as to perform RPC).
- In your implementation of this method, you must provide an interface that clients use to communicate with the service by returning an IBinder.
- You must always implement this method; however, if you don't want to allow binding, you should return null.
- goog_297321026Note: If a component calls bindService() to create the service and onStartCommand() is not called, the service runs only as long as the component is bound to it. After the service is unbound from all of its clients, the system destroys it.
- onDestroy()
- The system invokes this method when the service is no longer used and is being destroyed.
- Your service should implement this to clean up any resources such as threads, registered listeners, or receivers.
- This is the last call that the service receives.
Declaring a service in the manifest
- You must declare all services in your application's manifest file, just as you do for activities and other components.
- To declare your service, add a <service> element as a child of the <application> element.
- Here is an example:
- <manifest ... >
- ...
- <application ... >
- <service android:name=".ExampleService" />
- ...
- </application>
- </manifest>
- There are other attributes that you can include in the <service> element to define properties such as the permissions that are required to start the service and the process in which the service should run.
- The android:name attribute is the only required attribute—it specifies the class name of the service.
- After you publish your application, leave this name unchanged to avoid the risk of breaking code due to dependence on explicit intents to start or bind the service.
Note: You can ensure that your service is available to only your app by including the android:exported attribute and setting it to false. This effectively stops other apps from starting your service, even when using an explicit intent.