I am unable to understand
START_STICKY,
START_NOT_STICKY and
START_REDELIVER_INTENT
Can anyone explain clearly with examples.
I went through this link but couldn't understand it clearly.
These are related to services. We all know that services keeps on running in the background and they also consume some memory to execute.
So, as more of the application runs on android device, the device memory keeps on getting low and when the time arises, when the device memory gets critically low, the android system starts terminating processes, so as to release the memory occupied by the processes.
But you might be doing some important task with the services, that could also get terminated as the service stops. so these concepts are to tell the android system what action you want to perform when the device memory gets stable and when it is ready to relaunch the services.
The simplest explanation of these could be,
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.
START_NOT_STICKY- tells the system not to bother to restart the service, even when it has sufficient memory.
START_REDELIVER_INTENT- tells the system to restart the service after the crash and also redeliver the intents that were present at the time of crash.
Well, I read the thread in your link, and it says it all.
if your service is killed by Android due to low memory, and Android clears some memory, then...
STICKY: ...Android will restart your service, because that particular flag is set.
NOT_STICKY: ...Android will not care about starting again, because the flag tells Android it shouldn't bother.
REDELIVER_INTENT: ...Android will restart the service AND redeliver the same intent to onStartCommand() of the service, because, again, of the flag.
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 redelivery the same intent to onStartCommand().
This article by Dianne Hackborn explained the background of this a lot better then 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.
Related
I need to ulpoad data to a server in the Service?
As known Android system kills processes in case memory is low.
And any time my service can be killed till uploading wasn't finished?
How to avoid this trouble?
I want to call stopSelf() when uploading finished.
What constant I have to use to avoid this?
https://developer.android.com/reference/android/app/Service#START_CONTINUATION_MASK
How to avoid this trouble? I want to call stopSelf() when uploading
finished. What constant I have to use to avoid this?
You can use IntentService which will automatically shutdown when task is completed.
As known Android system kills processes in case memory is low. And any
time my service can be killed till uploading wasn't finished?
You can use startForeground service as
A started service can use the startForeground(int, Notification) API
to put the service in a foreground state, where the system considers
it to be something the user is actively aware of and thus not a
candidate for killing when low on memory.
For
What constant I have to use to avoid this?
Use
START_STICKY : to restart the service once Killed (intent will be null on restart)
START_REDELIVER_INTENT : to restart the service once Killed and get the same intent back which was received first time
Note: very few devices does not follow the START_STICKY and similar instructions.
Reference:
How to automatically restart a service even if user force close it?
do you have any idea what can bee root cause of my Android app service stop working when i run random another app/game?
I do not have code available, i just need causes.
Thank you.
Service runs in your app process. If your app is garbage collected, the service will stop until:
You start the service in new process via manifest file declaration
You make the service sticky (recommended).
go ahead and research above two and let me know if you would like more explanation or code
UPDATE
If you see official documentation of Service, Google clearly explains why and when service will be destroyed. What is useful in your scenario:
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
using startForeground will ensure your service keeps running in the same process. some pointers:
A service with attached client will not be destroyed even on low memory scenarios
A service will be killed in low memory scenarios, regardless of the process. Running in a different process is better but does not guarantee it won't be destroyed by system.
Don't use system.exit(0) to end your app. call finish() on activity.
Starting sticky service just ensures that service is restarted when memory is freed.
hope it helps!
Is having a foreground service protective for the entire process? The documentation is a bit unclear, saying the service is highly unlikely to be killed. However, I've learned there's a big different between a service (or an activity) being destroyed versus the process (which contains all the activities and services, unless you are specifically forcing your service to be in a different process) being killed.
Any ideas?
Thanks.
First off, nothing prevents a process from being killed, and unfortunately there is very little you can do about it. Android uses a modified form of Linux's "out of memory" process killer to periodically kill processes. Memory does not even have to be low for a task to be killed - it can simply have been running for too long. If you are root you can fiddle around with various files (under /sys or /proc, it's been a while since I have looked at this) in order to fight Android and try to keep a process from being killed, but unless you touch these files very rapidly (several times a second) Android will still likely to kill your process at an inopportune time.
Having a foreground service won't change any of this, it will merely bump your process to a higher priority so Android is more likely to kill other things first. But depending on what else you are doing it may still have little effect. For instance, I have a logger app which I wrote which takes 12-15MB of (non-shared) memory while running, and when foregrounded it still gets killed on a device with 512MB of RAM if I switch to (memory hungry) Firefox and do much of anything. Note that there are things you can do to recover from this, for instance, telling AlarmManager to send you an intent periodically, which if your service is killed will restart it. This will increase battery usage, however.
Now with regards to the Service itself versus the Activity class, Android can very well garbage collect your Activity after calling onPause without killing the process. In this case, for example, if you have a pointer to your Activity from your Service class you will find that it is suddenly null, so if you are referring to your Activity in this way you should always test for a null pointer before trying to call into a non-static member of your Activity.
I have a long running service which responds to multiple BroadcastReceivers (created in code, not manifest). Most of the time the service is running well, but from time to time it gets somehow stopped (the BroadcastReceivers stop to work) - I guess the system pauses it somehow (when I look into the running processes on the device I can clearly see the service is still "runnning").
I don't know the right reason why the service is being paused, but I'd like to know whether in these cases the onDestroy() method is called or whether there's a chance to handle this somehow.
I presume onDestroy() is not being called, because the service is still visible in the Running processes tab. I also have the service return the START_STICKY flag so the system should restart it whenever it's killed for memory reasons. Also if it is "paused" somehow, is it possible to create a WakeLock for this not to occur?
I know that the best solution would be to put all the BroadcastReceivers into the manifest and create a one shot-service called from their onReceive() methods. However I have chosen to go with the way of long running service because the initialization stage is very intensive it's better to initialize everything just once.
onDestroy() will be called only when service is being killed by lack of resources or when you explicitly stop it.
The service can be "paused" when your phone goes idle (usually when screen is off) because the CPU stops. To make services run always you should use PowerManager.PARTIAL_WAKE_LOCK - but use it wisely because it does not stop your CPU and thus draining the battery. You should never leave your apps running always. Just do what you need holding a WakeLock and then release it.
http://developer.android.com/reference/android/os/PowerManager.html
http://developer.android.com/reference/android/os/PowerManager.WakeLock.html
You can use AlarmManager to "wake" your apps periodically and do something.
http://developer.android.com/reference/android/app/AlarmManager.html
I am building an application where I need a service which will never stop like android system services. I can make my service restarted by system using start_not_sticky but there is no guarantee that my service will never stop. So my idea is if there is any way to broadcase receive when my service will be goes off I can restarted the service. Is there any way to receive that?
The documentation explains it best :
Use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory . (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
Note this means that most of the time your service is running, it may be killed by the system if it is under heavy memory pressure. If this happens, the system will later try to restart the service. An important consequence of this is that if you implement onStartCommand() to schedule work to be done asynchronously or in another thread, then you may want to use START_FLAG_REDELIVERY to have the system re-deliver an Intent for you so that it does not get lost if your service is killed while processing it