ANDROID Services
ANDROID
An Android service is an application component designed to perform long-running background operations without a user interface (UI)
Android Service
➔ An Android service is a type of long-running operation that runs in the background without providing any user interface (UI), allowing the service to remain active even while users are working in other apps.
➔ The services work silently in the background, so there is no need for a user interface.
➔ By default, services run on the main thread of their hosting process, meaning they do not automatically create their own threads. Therefore, service operations must be offloaded and run on a separate thread to avoid 'Application Not Responding' (ANR) errors.
➔ Android services have an independent lifecycle, so the service can continue to run even if the user moves to another application or the application that started the service is closed.
➔ The Android operating system monitors and manages the lifecycle of Android services and can shut them down if memory runs low.
➔ All services must be declared in the AndroidManifest.xml file to be recognized by the system, and this is called registering the service.
Types of Android Services
Foreground service: Performs tasks that are visible to the user, such as music playback or navigation, and requires a persistent notification to be displayed. They have high priority and are rarely killed.
Background services: Perform tasks that the user does not directly notice (e.g., data syncing).
Bound Service: It allows other components of the application (such as activities) to bind to it and provides a client-server interface for interaction. It only runs as long as another application component is bound to it.
Implementation of Android services
There are two possible ways to implement services and complete their lifecycle in Android.
Started service (unbounded service)
➔ A started or unbound service is a service that another component starts by calling startService() , which in turn calls the service's onStartCommand() method.
➔ When an unbounded service is launched, it has a lifecycle that is not dependent on the component that started it.
➔ The service can run indefinitely in the background, even if the component that launched it is destroyed or closed.
➔ A service should stop itself by calling stopSelf() when it is finished, or another component can stop it by calling stopService().
➔ Therefore, an unbounded service can be stopped in two ways: by calling the stopService() method or by stopping the service itself using the stopSelf() method.
Bounded Service
➔ A bound service is a service that allows application components to create a long-lasting connection by calling `bindService()` and it does not typically allow components to be started by calling the `startService()` method.
➔ This can be considered a server in a client-server environment. Components in an Android application can send requests to services and receive results. When an application component associates itself with a service by calling the `bindService()` method, that service is said to be bounded. To stop the execution of this bound service, all components must unbind themselves from the service using the `unbindService()` method.
Android services callback methods
To implement a user-defined or custom service, you need to create a generic class that extends the `Service` class. Then, you need to override certain callback methods with logic and actions to execute the service's operations in the application.
Figure: Service Life-Cycle Methods
Started Service Lifecycle
When a component (such as an activity) calls startService(), a service is "started".
onCreate(): This callback is called only once to perform initial setup when the service is first created.
onStartCommand(): This callback is called whenever a client requests to start the service. The service then continues to run in the background indefinitely.
onDestroy(): This callback is triggered when the service is stopped via stopSelf() (by the service itself) or stopService() (by another component).
Running state: The service continues to run even if the component that started the service is destroyed or stopped.
Bound Service Lifecycle
A service is "bound" when a component calls bindService() and it acts as a server in a client-server interface.
onCreate(): This is called when the service is created for the first time.
onBind(): This is called when a client binds to the service and must return an IBinder object for communication.
onUnbind(): This callback is triggered when all clients disconnect by calling unbindService().
onRebind(): This function is called if new clients connect after all previous clients have been disconnected and the onUnbind() function returns true.
onDestroy(): This callback is triggered when the system automatically destroys the service as soon as all clients unbind, unless it has been "started".