[android] START_STICKY and START_NOT_STICKY

What is the difference between START_STICKY and START_NOT_STICKY while implementing services in android? Could anyone point out to some standard examples.. ?

This question is related to android android-service

The answer is


Both codes are only relevant when the phone runs out of memory and kills the service before it finishes executing. START_STICKY tells the OS to recreate the service after it has enough memory and call onStartCommand() again with a null intent. START_NOT_STICKY tells the OS to not bother recreating the service again. There is also a third code START_REDELIVER_INTENT that tells the OS to recreate the service and redeliver the same intent to onStartCommand().

This article by Dianne Hackborn explained the background of this a lot better than the official documentation.

Source: http://android-developers.blogspot.com.au/2010/02/service-api-changes-starting-with.html

The key part here is a new result code returned by the function, telling the system what it should do with the service if its process is killed while it is running:

START_STICKY is basically the same as the previous behavior, where the service is left "started" and will later be restarted by the system. The only difference from previous versions of the platform is that it if it gets restarted because its process is killed, onStartCommand() will be called on the next instance of the service with a null Intent instead of not being called at all. Services that use this mode should always check for this case and deal with it appropriately.

START_NOT_STICKY says that, after returning from onStartCreated(), if the process is killed with no remaining start commands to deliver, then the service will be stopped instead of restarted. This makes a lot more sense for services that are intended to only run while executing commands sent to them. For example, a service may be started every 15 minutes from an alarm to poll some network state. If it gets killed while doing that work, it would be best to just let it be stopped and get started the next time the alarm fires.

START_REDELIVER_INTENT is like START_NOT_STICKY, except if the service's process is killed before it calls stopSelf() for a given intent, that intent will be re-delivered to it until it completes (unless after some number of more tries it still can't complete, at which point the system gives up). This is useful for services that are receiving commands of work to do, and want to make sure they do eventually complete the work for each command sent.


The documentation for START_STICKY and START_NOT_STICKY is quite straightforward.

START_STICKY:

If this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service. Because it is in the started state, it will guarantee to call onStartCommand(Intent, int, int) after creating the new service instance; if there are not any pending start commands to be delivered to the service, it will be called with a null intent object, so you must take care to check for this.

This mode makes sense for things that will be explicitly started and stopped to run for arbitrary periods of time, such as a service performing background music playback.

Example: Local Service Sample

START_NOT_STICKY:

If this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), and there are no new start intents to deliver to it, then take the service out of the started state and don't recreate until a future explicit call to Context.startService(Intent). The service will not receive a onStartCommand(Intent, int, int) call with a null Intent because it will not be re-started if there are no pending Intents to deliver.

This mode makes sense for things that want to do some work as a result of being started, but can be stopped when under memory pressure and will explicit start themselves again later to do more work. An example of such a service would be one that polls for data from a server: it could schedule an alarm to poll every N minutes by having the alarm start its service. When its onStartCommand(Intent, int, int) is called from the alarm, it schedules a new alarm for N minutes later, and spawns a thread to do its networking. If its process is killed while doing that check, the service will not be restarted until the alarm goes off.

Example: ServiceStartArguments.java


  • START_STICKY: It will restart the service in case if it terminated and the Intent data which is passed to the onStartCommand() method is NULL. This is suitable for the service which are not executing commands but running independently and waiting for the job.
  • START_NOT_STICKY: It will not restart the service and it is useful for the services which will run periodically. The service will restart only when there are a pending startService() calls. It’s the best option to avoid running a service in case if it is not necessary.
  • START_REDELIVER_INTENT: It’s same as STAR_STICKY and it recreates the service, call onStartCommand() with last intent that was delivered to the service.

KISS answer

Difference:

START_STICKY

the system will try to re-create your service after it is killed

START_NOT_STICKY

the system will not try to re-create your service after it is killed


Standard example:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}