Given a service that return START_STICKY from its onStartCommand:
1) The documentation mentions killing of the service, as far as I understand this, that is not done by calling Content.stopService, but done by the system if it needs resources (or my service could also crash which would be effectively the same - no clean shutdown) ?
2) How can I simulate the killing mentioned in 1) ? The killing is probably different from stopping (stoppping != killing ?) the service using the application menu in the settings, so I can't use this menu for testing purposes?
3) If my service is killed and then restarted, according to the documentation, only onStartCommand seems to be called, but not onCreate. So I conclude that variables of my service are persistet before my service gets killed? Or why does onCreate not get aclled? Or does it maybe?
My aim is to make sure that my service still works reliable when it was killed and restarted. Thanks for any hint :-)
Killing means its process being killed by the out of memory killer. You can simulate this from the adb shell -- use "ps" to find your app's process, and "kill" with the found pid to kill it. The system will after a few seconds restart the process and service.
If you are only receiving onStartCommand(), then your service and process was already running and didn't need to be re-created.
I had the same issue, and was wondering what is going on.
After reading the referenced post, I simply moved my code from onStartCommand(..) to onCreate(..) and it was working as expected.
Related
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!
I don't mind letting the application get killed by the Android OS, I'm trying to debug why the application is restarting after being killed by low memory situations. I'm using
adb shell dumpsys activity processes
To read the "Process LRU list (sorted by oom_adj):"
My current problem is when I do the following steps and read the dumpsys after each step.
App Running
Proc #)13: adj=fore /FA trm= 0 6124:com.thisoldthing (top-activity)
App closed by back button
Proc #20: adj=bak /B trm= 0 6124:com.thisoldthing (started-bg-ui-services)
Killed after running stressrobo
Proc #13: adj=svc /B trm=15 8488:com.thisoldthing (started-services)
Now the application is not killed when putting the device into a low memory situation. More worrisome is I want to know why it restarted.
Android will try to keep your service alive as long as possible. The documentation of Context.startService() says: "If any errors happen in the service's process, it will automatically be restarted." My understanding and experience let me believe that it will happen regardless you started with startService() or bindService(), but the last one has no mention to that though.
So, if you don't want get your service restarted, you need to close bound connections before kill it. Unfortunately the application can not rely in onDestroy() being called in killing conditions so any unbindService() calls will depend on application's life-cycle. You will need to handle it by yourself.
Finally, bind connections was not designed to remain forever. They should connect, do the job and unbind. Keeping this in mind, android does the right think restarting services with bound connections.
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.
I am aware that force killing an app is very bad, but the client requires it. I am required to implement a force reboot of sorts for the app. This is how I implemented it:
I create a BroadcastReceiver in my Application's (not Activity's) onCreate method. I have it wait for the REBOOT command to be broadcast. Upon receipt, I have it broadcast another message that has the services call stopSelf so that threads and services have a chance to exit cleanly. I then have an AlarmManager call my main activity 5 seconds later. Finally have my application kill itself with Process.kill(Process.myPid()). For the most part, it works, and I just need to add some extra waiting time before it kills the process (maybe by waiting for a TERMINATE broadcast from each running Service). My issue is this: while reviewing the logs, I found out that the system schedules the services to reboot. I'm worried about conflicts. Is there a way to terminate the services without any chance of it rebooting?
I fixed this by having the Receiver wait for all the services to finish their onDestroy() calls before having it die. I also changed from Process.kill() to ActivityManager.killBackgroundProcesses().
As a side note: I know it's wrong, but it really does feel cool killing the processes hehehe.
I'm developing an Android application that consists of:
a lightweight background service that logs events to a DB
a heavier GUI application that summarizes these events and displays graphs.
I'm having trouble creating the service part, though. The graphic application can use quite some RAM, and when it goes to the background, the OS closes it after some time of not being used.
The problem is, when the application gets shut down, so does the service. This is bad because this keeps me from recording further events. I don't care if the application gets terminated, but the service needs to keep on running.
I have tried numerous ways to keep the service alive, like having it use threads or a differently named process than the main app. Nothing has worked, and I have found no help on any of the android developer pages or forums.
Thank you for your advice!
Try to return START_STICKY in your service's onStartCommand(). Also how do you start your service? If you use bindService() with BIND_AUTO_CREATE flag it will be stopped automatically on unbindService(). You should explicitly start it with startService() and stop calling stopSelf(). Than OS keep your process running on the background after activity will be closed. Note: the activity and the service run in one process and it's imposible: "application gets terminated, but the service needs to keep on running". But it is possible to keep the process running without activities, with service running on the background.
Read the detailed info http://developer.android.com/reference/android/app/Service.html.
good luck!
You should use the AlarmManager to respawn your service. You just can't keep your service alive eternally.
Check about the lifecycle : http://developer.android.com/guide/topics/fundamentals.html