317

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

alex
  • 10,900
  • 15
  • 70
  • 100
prago
  • 5,225
  • 5
  • 25
  • 27

4 Answers4

432

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.

Community
  • 1
  • 1
Frank Leigh
  • 5,262
  • 1
  • 15
  • 18
  • 1
    How to avoid double calling to task handleStart(intent, startId); as both onStart() and onStartCommand will be called? is it a good design? @Frank Leigh – Sazzad Hissain Khan Nov 12 '13 at 16:33
  • Does the return code (e.g. START_STICKY or START_NOT_STICKY) have any influence on how Android selects services to be killed? – jmng Jun 04 '14 at 10:22
  • 2
    What is the default flag, though, if none is specified? – IgorGanapolsky Jul 14 '14 at 00:44
  • 3
    If you follow the "return super.onStartCommand(...);" you will see that in case your target sdk version is less than ECLAIR (API5=2.0) by default the START_STICKY_COMPATIBILITY is returned and from 2.0 and above START_STICKY is returned. – MikeL Jul 15 '14 at 12:27
  • 1
    What do you mean by "with no remaining start commands" in `START_NOT_STICKY`? – Malwinder Singh Jun 18 '15 at 05:45
  • There can only be one instance of a service. Therefore it's possible for startService() to be called and start commands queued up for a service after it is killed by the OS for resource reasons. Once the OS deems it's safe to recreate the service again, START_NOT_STICKY tells it to only start the service if there are pending start commands queued up for it. – Frank Leigh Sep 24 '15 at 00:30
  • I have a query here regarding this scenario : Let's say I am using start_Sticky and OS kills my service after sometime. Then let's say the user opens the app again and service is started using startService call. Does the OS again calls the service with null Intent when it feels enough resource is available? – nayakasu Dec 13 '16 at 12:59
  • I can't find doco on whether it calls onStartCommand() irrespective of whether it started again already. But it makes more sense that they will always call it and leave it to the developer to decide what they want to do with it. – Frank Leigh Dec 13 '16 at 23:02
  • 1
    @FrankLeigh Queued up? How? I mean it's queued for sure if it's an IntentService (in the IntentService's worker thread's event queue) but what if it's a not an IntentService? When this is theYou mean the event queue of the main thread? – stdout Mar 05 '17 at 18:51
  • This answer just needs +1 from me. – Stoycho Andreev Jun 21 '17 at 15:46
  • If I am not wrong. If there are pending intents ,whether any flag returned from OnStartCommand, It will be started anyways. These conditions are for the cases when service is running and no other call to StartService is there. – hitesh Aug 03 '17 at 08:57
  • 3
    @FrankLeigh I don't agree that `START_REDELIVER_INTENT` is like `START_NOT_STICKY`. Instead it is like `START_STICKY` – CopsOnRoad Feb 04 '18 at 09:22
131

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;
}
Oded Breiner
  • 28,523
  • 10
  • 105
  • 71
  • 6
    This actually not correct and confusing. It's a mistake saying: "service is killed" because one can think that you refer to stopSelf or stopService, while you obviously referring to process killed. So you better use the word process in your answer. – Ilya Gazman Dec 01 '16 at 00:41
  • Hi how I can test `START_REDELIVER_INTENT`. I just tested `START_STICKY` and kill the app by recent apps. Then it recall service. But `START_REDELIVER_INTENT` never called again. Why? – Asif Mushtaq Nov 04 '17 at 20:13
  • @IlyaGazman I respectfully disagree. Stopped and killed are two very different words. This answer explains the issue correctly in a simple and straightforward manner. – NoHarmDan Nov 13 '19 at 18:15
27

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

DocMax
  • 12,094
  • 7
  • 44
  • 44
Marvin Pinto
  • 30,138
  • 7
  • 37
  • 54
  • 1
    no luck guys.. I was not able to relate the documentation in layman's word. I would like to relate with a realtime scenario. I would like to show an example on the device. so that they can understand more easily. – prago Feb 03 '12 at 06:47
  • for START_STICKY and START_NOT_STICKY onStartCommand()will be executed only once and come out of it. I gone thru the sample u pointed out, but my doubt is how many times onStartCommand() will be executed. if I retrutn START_STICKY and still try to re-create the service, will the service executes onStartCommand then ?? – prago Feb 03 '12 at 12:50
  • what happens to activity when the service is re-created ? Is activity also re-created ? – ransh May 17 '16 at 20:52
  • I guess we'll never know – Denny Nov 18 '18 at 18:43
5
  • 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.
The General
  • 1,239
  • 2
  • 17
  • 28