About START_STICKY in Service - android

About using START_STICKY in Android Service.
official document says:
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;
This is understandable, so when an started service's process is killed due to lack of memory, the OS will automatically try to start the service again later.
My question is, if my code starts the service startService(...), and later stop it(e.g. I have a "STOP" button on my app's UI, when press it, I call stopService(...)), will system later start the service again? Or will the service instance be cleared from memory completely without later being created by system? (No service binding for this scenario)

START_STICKY- tells the system to create a fresh copy of the service, when sufficient memory is available, after it recovers from low memory. Here you will lose the results that might have computed before.
And answer for your query is the service only recreate if it's killed by the OS in any circumstances when working with START_STICKY. if we were terminating the service why android need to reproduce it again.if your using stopSelf() the service does not recreate even it is sticky.

I have had that stopService() button in my app during testing. Once you stop it using the command, it will not start again until you call startService().

Android kill the process from time to time. However Sticky service is recreated automatically by android system. Somebody told, Sticky services are destroyed and are recreated after 5 seconds.

START_STICKY is the operation mode of the started services, depending on the value they return from on StartCommand() method.START_STICKY is used for services that create the copy of service but it won`t store any result of services which is performed before.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Logs.d(TAG, "# Service - onStartCommand() starts here");
// If service returns START_STICKY, android restarts service automatically after forced close.
// At this time, onStartCommand() method in service must handle null intent.
return Service.START_STICKY;
}

Related

Android Service for playing music: why START_STICKY?

I am working on an android app to play music.
So far I have returned START_STICKY from the onStartCommand of the Service responsible for playing the music without much thought becuase the tooltip in Eclipse states: "This mode makes sense for [...] a service performing background music playback".
The first thing this method does is looking in the intent what it is supposed to do (play, stop, next song, ...).
Recently when I killed the app while playing music (by dragging it out of the screen in the overview of recent apps) the app crashed. Looking in the log file I found that a NullPointerException was thrown when trying to access the intent in onStartCommand (after the Apllications's and Service's onCreate methods had been called).
My first reflex was to therefore insert at the beginning of the onStartCommand method:
if (intent == null){
stopSelf();
return START_NOT_STICKY;
}
But after reading the descriptions of START_STICKY and START_NOT_STICKY again I am wondering: Why would START_STICKY be recommended for a music player?
The way I understand it is that the difference between the two is that if a service started with START_STICKY is killed it will be restarted (then with intent=null). With START_NOT_STICKY the service will not be restarted (unless the user requests it), therefore it will always be called with an intent and I would not need to check whether it is null or not.
When the user kills the app it seems obvious to me that the service should not be restarted.
The other case I can think of where the service might be restarted is if the service had been killed by the system due to a lack of ressources. In that case, too, I don't think a user would want the music to unexpectedly start playing music just becuase some ressources became available.
The following two answers imply that the return code has no other meaning than whether the service should be restarted if the process was killed:
What is START_STICKY,START_NOT_STICKY and START_REDELIVER_INTENT
Service
START_STICKY and START_NOT_STICKY
Why is START_STICKY recommended for a music player?
START_STICKY- If the service is stopped due to low memory then service is recreated when sufficient memory is available, after it recovers from low memory. Here you will lose the results that might have computed before.
START_NOT_STICKY- If the service is stopped the system not to bother to restart the service, even when it has sufficient memory.
Also when user kills the app the service wont be stopped unless you stop the process by using some task killers.For more info on service check this link.
http://www.vogella.com/tutorials/AndroidServices/article.html
int START_STICKY:
Constant to return from onStartCommand(Intent, int, int): 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.
so it is self-exolanatory refer this STICKY SERVICE

Restart android service once it is stopped when application closed through task manager

I was using a service which will update my application whenever new update is available in server. So my service run and it always check with server for version update and if i get new version update it will install.
My issues whenever i closed my application form taskmanager my service is getting killed. I used START_STICKY in onstartcommand() also even though it is not working. Is their is any chance to restart my service once it is stopped by taskmanager.
You can use AlarmManager to periodically wake up your application (i.e. activity or a service). This way you won't need to run service in the background all the time.
Just set AlarmManager to wake your app/service every day/week, check for an update, and then close the service. Check out this tutorial on how to use AlarmManager.
This approach will be better than running your own service, because it'd use no memory or battery power. Your users will thank you for that!
If your application is designed to run on API level 21 or newer (which means Android 5.0 Lollipop), you can also take advantage of JobScheduler. It might be useful, i.e. it could schedule update check to run when device is plugged in, to further save power.
From the docs:
Notice that the onStartCommand() method must return an integer. The integer is a value that describes how the system should continue the service in the event that the system kills it (as discussed above, the default implementation for IntentService handles this for you, though you are able to modify it). The return value from onStartCommand() must be one of the following constants:
START_NOT_STICKY
If the system kills the service after onStartCommand() returns, do not recreate the service, unless there are pending intents to deliver. This is the safest option to avoid running your service when not necessary and when your application can simply restart any unfinished jobs.
START_STICKY
If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with a null intent, unless there were pending intents to start the service, in which case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.
START_REDELIVER_INTENT
If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand() with the last intent that was delivered to the service. Any pending intents are delivered in turn. This is suitable for services that are actively performing a job that should be immediately resumed, such as downloading a file.
Have you tried to return the onStartCommand() with START_REDELIVER_INTENT ?
You can owerride this method onTaskRemoved to start service again via BroadcastReceiver.

Precise Semantics of START_STICKY flag for Android Service

Somehow I am having a hard time parsing the official description of the START_STICKY flag:
Constant to return from onStartCommand(Intent, int, int): 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.
Specifically, the following four parts do not make technical sense (aka make me go WTF):
"if this service's process is killed ..., then leave it in the started state" [how do you leave something that is killed in the started state?]
"Later the system will try to re-create the service. Because it is in the started state, ..." [why is it in the started state if the system is trying to re-create the service?]
"Because it is in the started state, it will guarantee to call onStartCommand(...) ..." ["it will guarantee to call"? sorry, can't parse that phrase linguistically]
"This mode makes sense for things that will be explicitly started and stopped to run for arbitrary periods of time, ..." ["and stopped to run"??]
Does anybody have a better spec of this flag? And, to any Googlers reading this: wtf? Can you get it fixed internally pronto?
As you know, there are two forms a service can have in Android:
Started service
Bound service
The key point to understanding the description is that a Started service must manage its own lifecycle, i.e. the ONLY components that can stop the service is the service itself by calling stopSelf() or another component by calling stopService(). Once a Started service has been started (onStartCommand() returns) it’s in a started state and it won't stop unless either stopSelf() or stopService() is called. So, if the system prematurely kills the service (neither stopSelf() or stopService() has been called), the service still is considered to be in a started state. And it’s up to you to tell (signal to) the system how to proceed with the service after killing it by returning a flag in onStartCommand().
Probably the description of the START_STICKY flag given at the end of Extending the Service class will be more clear for you.
P.S. Regarding the "and stopped to run??" confusion, try reading it as "...explicitly started and stopped in order to run..."
EDIT:
Also take a look at this question.
START_STICKY and START_NOT_STICKY
START_STICKY tells the OS to recreate the service after it has enough memory and call onStartCommand() again with a null intent

Foreground service still alive even though its process dies in a crash

I have a Service running in the foreground, and an Activity that interacts with it. If the Activity crashes, Android kills the entire process, including the foreground Service and its associated Threads.
However, the ongoing notification provided by the Service does not go away, and upon closer inspection, Android's task manager reveals that the Service itself is still running.
How can I kill the foreground Service in this circumstance?
Have you override onStartCommand method of the Service? What value is it returning? If not, try to override it and return START_NOT_STICKY from it.
START_STICKY: If this service's process is killed while it is started, then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service.
START_NOT_STICKY: If this service's process is killed while it is started, and there are no new start intents to deliver to it, then take the service out of the started state and don't recreate.
Not sure, as I have never worked on foreground services, but this might be the reason.
Are you sure the service is not running it its own process...
Also can you confirm whether the service is getting restarted..If its getting restarted-it is because you are returning START_STICKY from onStartCommand()

android - service stops when activity is destroyed

when I open the activity of my project I call the startService(Intent intent) method to start a new Service.
When the activity is destroyed the service shouldn't be killed (because I didn't use the bindService() method), but the fact is that when I close my activity the service is killed and after a second the system creates a new Service (I verified that, the system calls again the onCreate() method of my service). What do I have to do to keep only one service ? Thank you
To have a service running independently of your application's main process and to be sure that Android does not kill it while it's doing something, there are two things you should do/try.
Run your service in a separate process. You can achieve this by adding the following attribute to your service declaration in the manifest:
android:process=":somenamehere"
When your service is running and you do not want it to be killed by the OS, you have to use the startForeground(int id, Notification notification) method. When the service finishes whatever is doing and can be killed by the OS, call stopForeground(boolean removeNotification). "startForeground" requires a notification as argument because every foreground service must display a notification so the user realizes about it
I hope this helps you.
I mean I hold the home button and then kill my activity from the list of app open
That does not "close" an activity. That terminates your process. The user is welcome to terminate your process whenever the user wants, whether via this means or through third-party task manager apps. There is nothing you can do about this -- you cannot stop the user from terminating your process. Since your process will stop for other reasons as well (e.g., sheer old age), you have plenty of reasons to handle this case.
Edit: Please refer to CommonsWare's answer
Old answer: You should override public int onStartCommand(Intent intent, int flags, int startId) method and return START_STICKY value as the mode of your service.
this will keeps your service working when the activity is destroyed or even when you exit your app unless you call stopService(Intent) explicitly

Categories

Resources