As an android developer you must have know the major components of android in very detailed manner. If not don’t worry!!
Today I am writing here to help you guys to get through one of the major component of Android i.e. “Service”. If you are a beginner you would probably think why we would need services in our coding. If this is the case you might becomes the services FAN 😉 by the end of this tutorial.
You will understand how important role a service will play for a developer. Eventually you will come to know that they always play a important role in designing when you integrate them with web services, or have an application logic which will bound you beyond the UI i.e. If you need to start long running tasks in response to user input, then you should not expect the UI to wait for the result.
A service is an application component that implements and performs long running operations in the background without any need to interact with the user. Services also handle the background processing associated with the application. A service started by an application will be continuing to running in background even when user switches to another application component.
While developing services, you must always have few key questions in your mind like:
You will get the answers of all these questions by the end of this tutorial. I will explain each in a very good detail.
In android we have following two states that are essentially taken by a service.
Lets see these states in a bit more detail:
Started: A service is started with calling startService() by an application component (such as an activity). A service is once started it will keep running in the background for indefinite time even if the component that started is destroyed. A single operation is performed by a started service and it doesn’t return any result to the caller.
Bound: A service is bound by an application component by calling bindService( ). A bound service allows an application component to interact with service by offering a client-server interface that enables a component to send requests, get results and even do so across processes with inter-process communication (IPC). A bound service runs as long as another application component bound to it. Multiple components can be bind to a service but when all of them unbind, the service is destroyed.
In the remaining tutorial I will be going to explain you how to start, stop and create a service and the service life cycle. Let’s have a look on each one by one.
How to Start a service
A service can be started from an activity or other application by passing an intent (specifying the service to start) to startService(). The android system calls the service’s onStartCommand() method and passes it the intent. onStartCommand() can be never called directly. Following is an example shows that an activity can start the example service in the previous section (HelloService) using an explicit intent with startServie().
Intent intent = new Intent(this, HelloService.class); startService(intent);
If there are multiple requests to start the service then it results in multiple corresponding calls to the service’s onStartCommand(). However, only one request to stop the service (with stopSelf() or stopService()) is required to stop it.
How to Stop a service:
A started service must manage its own lifecycle. It means the system doesn’t stop or destroy the service unless it must recover system memory and service continues to run after onStartCommand() returns. So the service must stop itself by calling stopSelf() or another component can stop it by calling stopService(). System will destroy the service as soon as possible once it requested to stop with stopSelf() or stopService().
How to Create a service (unBounded):
Creating a started services
A started service can be defined as the service which another component starts by calling startService(), results in a call to service’s onStartCommand() method. This started service has a lifecycle that is independent of the component that started it and service will keep running in background for indefinite time ,even the component is destroyed that started the service. When its job is completed it should stop itself by calling stopSelf() or another component will stop it by calling stopService().
The service can be started by an application component such as an activity by calling startService() and passing an intent that specifies the service and includes any data for service’s use. This intent is received by service onStartCommand() method.
For instance some data needs to be store on online database by an activity. Then activity can start an associated service and deliver the data to save by passing an intent to startService(). The intent is received by the service in onStartCommand(), which connects to the internet and perform a database transaction. Service will stop itself and destroyed when the transaction is completed.
NOTE: By default a service runs in the same process as the application and main thread of the application by which it is declared, so if this service performs extensive or obstructing operation while a user is interacting with an activity in same application then this service will slow down the activity performance. A new thread should be start inside the service in order to avoid impact on application performance.
Conventionally there are following two types of classes that can be extend to create a started service:
Service: Service class is the base class for all the services. Its important to create a new thread in which you should do all the services work. Because service uses main thread of your application by default which can cause slow performance of an activity your application is running.
IntentService: This class can be defined as the subclass of services. A worker thread is used by this subclass to handle all start requests one at a time. It is a best option for you, if you don’t want your service to handle multiple requests simultaneously. So now you need to do is implement onHandleIntent(), which will receive intent for each start requests so you can do the background work.
Creating a bound service
A bound service can be defined as a service which allows application component to bind it by calling bindService(). It creates a long standing connection and generally doesn’t allow component to start it by calling startService().
Bound service should be created when you want to interact with service from an activity and other components of your application or to expose some of your application’s functionality to other application through inter-process communication (IPC).
For the creation of bound service, on implementing the onBind() call back method, it returns an iBinder for defining an interface for communication with service and then other application components can call bindService(). There service only serves to the application which is bound to it, so when there are no components bound to the service, it destroyed by the system. If any service started through onStartCommand() you must stop the service in the way whereas you don’t need to stop a bound service in the way.
The first thing you must do is define the interface that specifies how a client can communicate with the service while creating a bound service. This interface between the service and a client must be implemented by IBinder and it should be what your service must return from the onBind() callback method. Client can begin interacting with the service through the interface once the client receives the ibinder.
Multiple clients can bind to the service at a time. When a client’s interaction with service is done, it calls unbindService() to unbind. If there are no clients bound to the service , the system destroys the service.
Sending notification to the user
If any service is running, it can give the notification to the user of events using Toast notification or Status Bar Notification.
A toast notification can be defined as the message which appears on the surface of current window for a moment then disappears.
Status Bar Notification can be defined as a message which appears in the status bar with a message, which the user can select in order to take an action such as start an activity.
Generally status bar notification is a best technique, it can be used when some background work has been completed like as download completed, so the user can take an action on it. When the user selects a notification from the expanded view then it starts an activity such as showing downloaded file.
Running a service in the foreground
A foreground service can be defined as the service that is considered to be the service the user is actively aware about. Foreground service must provide a notification for the status bar, which is placed under the ongoing heading. It means unless the service is either stopped or removed from the background, the notification can not be dismissed.
For example, a music player that plays music from a service should be set to run in the foreground, because the user is explicitly aware about its operation. The notification in the status bar might indicate the current song and allow the user to launch an activity to interact with the music player.
If you want your service to run in the foreground it can be requested by calling startForeground(). This method takes only two parameters one is integer that is used to identify the notification and the notification for the status bar.
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), System.currentTimeMillis()); Intent notificationIntent = new Intent(this, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, getText(R.string.notification_title), getText(R.string.notification_message), pendingIntent); startForeground(ONGOING_NOTIFICATION_ID, notification);
Note: – The integer id given to startForeground() must not be 0.
The service from the foreground may be removed by calling stopForeground(), this method takes a Boolean , which indicates whether to remove the status bar notification as well. The service doesn’t stop by this method, however if service is stopped, it is still running in the foreground and the notification is also removed.
Service life cycle
A service has lifecycle callback methods that can be implemented to monitor the changes in the service’s state so that you can perform work at the appropriate stage. The following diagram illustrates a lifecycle of service. Left side of diagram shows the lifecycle when the service is created by calling startService() and the right side of diagram shows the lifecycle when the service is created by calling bindService().
The service base class defines variety of methods and most important methods are given below. There is no any need of implement all the callback methods, however it’s important to understand each method and implement those that ensure your application’s behavior according to the user’s expectations. Following are the lifecycle methods.
The code below will describe how you can define a service and its methods in coding:
public class ExampleService extends Service { @Override public void onCreate() { ... } @Override public int onStartCommand(Intent intent, int flags, int startId) { ... } @Override public IBinder onBind(Intent intent) { ... } @Override public boolean onUnbind(Intent intent) { ... } @Override public void onRebind(Intent intent) { ... } @Override public void onDestroy() { }
The entire lifetime of a service can be defined as the time difference between the time onCreate() ,is called and the time onDestroy() returns.
Managing the lifecycle of service
The difference between the times from when a service is created to the time when it is destroyed is known as the lifecycle of a service.
The life cycle of a service is much simpler than that of an activity. However it is much more important to pay a close attention to the lifecycle of services because it tells you when your service is created and when your service is destroyed. Usually the service runs in the background without letting the user know about it.
Implementation of lifecycle callbacks
Like an activity, a service has lifecycle callback methods. These methods can be implemented to monitor the changes in state of service and perform work at appropriate times. Following is the demonstration of each of the lifecycle callback methods in skeleton services.
public class ExampleService extends Service { int mStartMode; // indicates how to behave if the service is killed IBinder mBinder; // interface for clients that bind boolean mAllowRebind; // indicates whether onRebind should be used @Override public void onCreate() { // The service is being created } @Override public int onStartCommand(Intent intent, int flags, int startId) { // The service is starting, due to a call to startService() return mStartMode; } @Override public IBinder onBind(Intent intent) { // A client is binding to the service with bindService() return mBinder; } @Override public boolean onUnbind(Intent intent) { // All clients have unbound with unbindService() return mAllowRebind; } @Override public void onRebind(Intent intent) { // A client is binding to the service with bindService(), // after onUnbind() has already been called } @Override public void onDestroy() { // The service is no longer used and is being destroyed } }
Service and android manifest
I hope you enjoyed the lifecycle details and will try the service very soon next time whenever you code. Let us now have a look on how you can define your service in the manifest file son that your activity and your application must know that a service is going to be handled soon!!!!
Make sure you must declare your manifest into the manifest otherwise your app will got crash and it won’t run.
I will explain this to you with a short example. Try the code given below:
<manifest ... > ... <application ... > <service android:name=".ServiceExample" /> ... </application> </manifest>
This is how you declare your service in manifest file.
If it is a critical case in which you are uncertain as to which service should start first ,intent filter can be a good option. But you must set the package of the intent with setPackage(), which provides sufficient certainties for target service. Furthermore you can ensure that your service is available to only your app by including the android: exported attribute and setting it to “false”. It prevents other apps from starting your service adequately even when you are using an explicit intent.
That’s it!!! 🙂
Top 10 Android App Development Trends | 2020 Guide
Top 15 Best Android Apps For C Programming | 2018 Exclusive
5 Best Resources to Get Started with Android Nougat
Android Studio Introduction
Applying MediaCodec On An Open Source Android Audio Player
5 Most Used Android Testing Frameworks
Android Language Highlights A Developers Perspective
Android KitKat Development