Regarding onStartCommand return flags

from the CommonsWare Community archives

At February 21, 2021, 9:29am, root-ansh asked:

I read this about flags in an article:

When a START_STICKY service is killed by system, it restarts with following arguments

  1. If there is any pending intent to be delivered, it is passed to onStartCommand otherwise null is passed.

  2. If service is killed before completing onStartCommand, next time service if restarted with flags = Service.START_FLAG_RETRY

In this case, service is only started if these is any pending intent to be delivered.

It is same as START_STICKY with following differences

  1. Service is restarted with last intent passed to service.

  2. On restarting, Service.START_FLAG_REDELIVERY is passed to onStartCommand flag.

what is the meaning of pending intent in here? from what i know, context.StartService() can be called a million times and will still start a service only once, so how would that really work? Like, do these calls get simply ignored if a service is already running or do they get stored in some kind of system queue? and if the system decided to kill my service, would it consider all the previous calls made to context.sStartService() made via the previously opened activity?

Side question 1 > killing the app from settings >> force stop will completely kill all the processes and running components of the app right? will these flags matter then?

Side question 2 > why would anyone want to return START_NON_STICKY ? from the definition , this looks like a flag telling the system to not start a service at all

At February 21, 2021, 6:11pm, mmurphy replied:

If you call startService() a million times, the service will be created only once. However, onStartCommand() will be called a million times. Since startService() could be called from background threads, it is possible that there are multiple Intent objects pending that have not yet been delivered to onStartCommand().

They get queued.

Usually yes.


AFAIK, no. That is the reason for my “usually yes” response earlier: “Force Stop”, and things that behave like it, probably cause you to lose those undelivered Intent objects.

Nowadays, I expect that this will not be all that useful, mostly because of the limitations on started background services added in Android 8.0.

In earlier Android years, though, START_NOT_STICKY had its uses. This flag says “if you terminate my process, do not automatically restart the service”. In other words, the service should run normally, but only as long as the process does.

The example that I think that I used in The Busy Coder’s Guide to Android Development is a music player. Suppose that we had a music player that used a background service on older Android versions. It is busily playing music, minding its own business… and Android terminates the process due to low memory conditions. If that service used START_STICKY, then some time later, Android would fork a fresh process for the app and start up the service again automatically. If the service then started playing music automatically… we do not know if the user wants music right now. IMHO, START_NOT_STICKY would be the preferable choice here: if the music stops on its own, let the user decide when the music should resume playback.