A service is an application component that can run some long running task in the background without the need for a user interface. Some other application component can start the service and this service will then keep on running even if the user switches to another application.
A service can essentially take two forms:
Unbounded
A service is "started" when an application component (such as an activity) starts it by calling startService(). Once started, a service can run in the background indefinitely (unbounded), even if the component that started it is destroyed. Usually, a started service performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is done, the service should stop itself.
Bound
A service is "bound" when an application component binds to it by calling bindService(). A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC). A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.
SERVICE LIFE CYCLE :-
These are the main callback method in Service life cycle -
onStartCommand()
This method calls when the service is started by calling startService(). (In case of StartedService )
onBind()
This method called when the service is started by calling bindService() . (in case of Bound Service).
OnCreate()
This method called when the service is creating very first time.
OnStart()
This is method called when the service is about to start .
Ondestroy()
This method is called when the service is about to destroy.
Implementation and declaration
<service
android:name="MyService"
android:icon="@drawable/icon"
android:label="@string/service_name">
</service>
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
return Service.START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
}
Start a service
// use this to start and trigger a service
Intent i= new Intent(context, MyService.class);
// potentially add data to the intent
i.putExtra("", "");
context.startService(i);
Service.START_STICKY:
Service is restarted if it gets terminated. Intent data passed to the onStartCommand method is null. Used for services which manages their own state and do not depend on the Intent data.
Service.START_NOT_STICKY:
Service is not restarted. Used for services which are periodically triggered anyway. The service is only restarted if the runtime has pending startService() calls since the service termination.
Service.START_REDELIVER_INTENT:
Similar to Service.START_STICKY but the original Intent is re-delivered to the onStartCommand method.
IntentServices :
You can also extend the IntentService class for your service implementation
IntentService is a a base class for Service that can be used to handle asynchronous work off the main thread by way of Intent requests on demand. Each intent is added to the IntentService’s queue and handled sequentially. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
public class MyWebRequestService extends IntentService{
@Override
protected void onHandleIntent(Intent intent) {
}
}
Difference between Service & Intent service:
Service: It is the base class for the Android services, that you can extend for creating any service. Since the service run inside the UI thread, it requires that you create a working thread for execute its work.
IntentService: it is a subclass of Service, that simplifies your work. It works already in a working thread, and can receive asynchronous request. So, you don't need to create it manually, or to worring about synchronization. You can simply extend it and override the method:
onHandleIntent(Intent intent)
where you can manage all the incoming request.
Taking a look at the documentation, you can see in details what the IntentService do for you:
Creates a default worker thread that executes all intents delivered to onStartCommand() separate from your application's main thread.
Creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you never have to worry about multi-threading.
Stops the service after all start requests have been handled, so you never have to call stopSelf().
Provides default implementation of onBind() that returns null.
Provides a default implementation of onStartCommand() that sends the intent to the work queue and then to your onHandleIntent() implementation.
So, if you need more control you can use the Service class, but often for a simple service the best solution is the IntentService.
Difference between unbound and bound service:
Bound Service :Service which call indefinitely in between activity
An Android component may bind itself to a Service using bindservice (). A bound service would run as long as the other application components are bound to it. As soon as they unbind, the service destroys itself.
Unbound Service :Service which call at the life span of calling activity
In this case, an application component starts the service, and it would continue to run in the background, even if the original component that initiated it is destroyed. For instance, when started, a service would continue to play music in the background indefinitely.
Communication with services
1.Using Intent data.
2.Using receiver.
Handler and ResultReceiver or Messenger
Activity, Service, Handler:
An Activity starts up a Service. The Activity needs a way of communicating with the Service, so it passes a ResultReceiver object to the Service class. This ResultReceiver provides the communication link between the Service's behavior and the Activity.
The Service stores a reference to the ResultReceiver before it does anything else. The Service then starts up a sequence of related tasks using a Handler, and the Service itself is bound to the Handler by passing itself as an instance of a callback object.
Through this last step, the Handler can signal to its callback object -- the Service -- that the Handler's work is done, and the Service can tell its reference to ResultReceiver to pass a message back to the Activity.
The ResultReceiver in the Activity can interpret the message based on the integer result code. If the Activity is still visible, then the ResultReceiver can show a confirmation (or an error message) and we can see a confirmation that the work was finished.
If the service should be communicating back to the activity, it can receive an object of type Messenger via the Intent data it receives from the activity. If the Messenger is bound to a Handler in the activity, the service can send objects of type Message to the activity.
A Messenger is parcelable, which means it can be passed to another process and you can use this object to send Messages to the Handler in the activity.
Messenger also provides the method getBinder() which allows passing a Messenger to the activity. The activity can therefore send Messages to the service.