Defining custom services


1. Implementation and declaration

A service needs to be declared in the AndroidManifest.xml file and the implementing class must extend the Service class or one of its subclasses.

The following code shows an example for a service declaration and its implementation.
 
<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;
  }
}

2. Start a service

An Android component (service, receiver, activity) can trigger the execution of a service via the startService(intent) method.
// use this to start and trigger a service
Intent i= new Intent(context, MyService.class);
// potentially add data to the intent
i.putExtra("KEY1", "Value to be used by the service");
context.startService(i);
 
Alternatively, you can also start a service via the bindService() method call. This allows you to communicate directly with the service. We discuss that later.

3. Service start process and execution

If the startService(intent) method is called and the service is not yet running, the service object is created and the onCreate() method of the service is called.

Once the service is started, the onStartCommand(intent) method in the service is called. It passes in the Intent object from the startService(intent) call.

If startService(intent) is called while the service is running, its onStartCommand() is also called. Therefore your service needs to be prepared that onStartCommand() can be called several times.

What if you call this method twice in your code? Do you have to worry about synchronizing the onStartCommand() method call? No, this method is called by the Android system in the main user interface thread, therefore it cannot be called simultaneously from two different threads.
A service is only started once, no matter how often you call the startService() method.

4. Service restart behavior

In its onStartCommand() method call, the service returns an int which defines its restart behavior in case the service gets terminated by the Android platform. You can use the constants, the most common options are described by the following table.
Table 1. Restart options
Option Description
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.
You can check if the service was restarted via the Intent.getFlags() method. START_FLAG_REDELIVERY (in case the service was started with Service.START_REDELIVER_INTENT) or START_FLAG_RETRY (in case the service was started with Service.START_STICKY) is passed.

5. Stopping a service

You stop a service via the stopService() method. No matter how frequently you called the startService(intent) method, one call to the stopService() method stops the service.
A service can terminate itself by calling the stopSelf() method. This is typically done if the service finishes its work.

No comments:

Post a Comment