In my activity I implement onstop(),onstart(),onstart()
I start and bind my service. My service extends IntentService
so onStop() I just call unbindService().
Then I go Settings of my device and open Running tab-> show cached processes
I see that:
when a touch back key. in show cached processes my service has still.
when a touch home key. in show cached processes my service has gone.
Both of them call onstop().
So can anybody can tell me why there have 2 cases like this? Or is this is a misunderstanding about the lifecycle of Service and Activity.
I can't tell you why there are 2 cases like that. However, I can tell you that whether a service is cached or not by the Android OS is not dependent on what button you use to call onStop(). The decision to cache a process is made by the OS depending on how much memory is needed by the service and how often you use it among several other factors.
To quote Google on this matter: " It may cache processes that you’ve been using recently in RAM, so they restart more quickly when you open them again, but it will erase the cache if it needs the RAM for new activities." [1]
[1] - http://support.google.com/mobile/bin/answer.py?hl=en&answer=168921
Related
I'm trying to find the official documentation about the Android Application class lifecycle. Apparently, for what I found on StackOverflow here and here the Application class can be killed if the system needs memory. Even this tutorial says so.
But few things irritates me a bit about this:
I can't find an official documentation telling me that yes, the Application class can be killed on low memory.
I can't find any official diagram representing the Application lifecycle neither.
I can't find any proper callback to use when the Application class is killed except onLowMemory(). Does it mean that I have to use this method to persist my data?
If the Application class is killed on low memory pressure and the app comes to foreground again, how can I know in its onCreate() that the app has been recreated after a system kill? In an Activity I would test the savedInstanceState, but as far as I know there is nothing similar in the Application class.
Thank you for your enlightenments.
I can't find an official documentation telling me that yes, the Application class can be killed on low memory.
Below are the references to where it's been stated:
Application Fundamentals
Processes and Threads
Multitasking the Android Way
I can't find any official diagram representing the Application lifecycle neither.
This is a reasonable observation... Although the following is opinion-based, my best guess is that such a diagram would contradict the Android's multitasking "philosophy" as described in the last reference provided:
"A key to how Android handles applications in this way is that processes don't shut down cleanly. When the user leaves an application, its process is kept around in the background, allowing it to continue working (for example downloading web pages) if needed, and come immediately to the foreground if the user returns to it. If a device never runs out of memory, then Android will keep all of these processes around, truly leaving all applications "running" all of the time."
I can't find any proper callback to use when the Application class is killed excepted onLowMemory(). Does it mean that I have to use this method to persist my data?
Regarding onLowMemory() whose description is quite straightforward, are we talking about a background process or foreground UI?...
If none of application Activities is in foreground and OS is low on memory, it may kill the app so that none of the Application's or the app component's (Activity, Service) callbacks will be invoked. That said, (since you're dealing with Activities) I recommend to store all persistent data as per the documentation, in onPause().
If the Application class is killed on low memory pressure and the app comes to foreground again, how can I know in its onCreate() that the app has been recreated after a system kill?
You can't recognize it in Application's onCreate().
As far as I know, you can't handle the application killed event. Here is a quote from the Application's onTerminate method:
This method is for use in emulated process environments. It will never
be called on a production Android device, where processes are removed
by simply killing them; no user code (including this callback) is
executed when doing so.
The general idea is that you shouldn't care whether the application was killed or not. If it was, the OS will restart the app next time it is needed otherwise it will be resume (and you'll use the Activity / Fragment lifecycle events to achieve this).
What data do you need to store - is it possible to store it earlier (when it is received from web service and so on) instead of waiting for the last moment?
With respect to Process lifecycle, Android system tries to maintain an application process for as long as possible, but eventually needs to remove old processes to reclaim memory for new or more important processes. To determine which processes to keep and which to kill, the system places each process into an "importance hierarchy" based on the components running in the process and the state of those components. Processes with the lowest importance are eliminated first, then those with the next lowest importance, and so on, as necessary to recover system resources.
One of the classification is :
Foreground Process : A process that is required for what the user is currently doing. A process is considered to be in the foreground if any of the following conditions are true:
1. It hosts an Activity that the user is interacting with.(the Activity's onResume() method has been called).
2. It hosts a Service that's bound to the activity that the user is interacting with.
3. It hosts a Service that's running "in the foreground" —the service has called startForeground().
4. It hosts a Service that's executing one of its lifecycle callbacks (onCreate(), onStart(), or onDestroy()).
5. It hosts a BroadcastReceiver that's executing its onReceive() method.
What can be real life examples of scenarios given above I am asking this because it will help me and others as well in differentiating between this situations.
1)THe app that is currently on top of the stack (the one the user is using)
2)An app with an Activity that has called bindService on any service. The idea is that if it killed that service, it might lose data. An example of this would be a facebook app, which has a background service to fetch data every so often. If the user has it open, it would qualify
3)This is a service that has declared that its feeds data to a UI. An example of this would be a facebook app where the user didn't have an activity with it open
4)This is a service that's just starting or just finishing. This would be pure luck to have happen, but its basically saying it will try to let it start up or finish cleanly before killing it
5)This is any app that's currently responding to an event. An example would be an SMS app that was just notified of an incoming SMS and needs to deal with it. It will be allowed to run until its done, because doing otherwise may lose data.
I have a service that also contains an activity the problem is sometimes it gets shut down by the operating system.
How can I prevent that from happening?
Not sure what you mean by "service that contains an activity".
The OS can and will shut down services based on demand for memory. How often this happens depends on what you have running on your device, and the amount of memory that your device has.
To try to minimize this, you can call Service.startForeground(). Please read the javadocs for the proper usage, and please look at stopForeground() as well.
Note that this is still no guarantee. You must author your app to gracefully handle when your service is destroyed. Please read up on the Service lifecycle to understand how to handle this.
Even if you could keep your service running at all times, it would be a bad idea. This is not a personal computer plugged in to AC power. A service that is perpetually running will greatly effect the battery life of the device.
It doesn't make any sense that you would have a service that contains an activity. You can have a service to which an Activity is connected, but not one that holds an Activity. Services, along with the rest of your app, can be killed off by the Android OS at any time, and will be restored when the user navigates back to them. Instead you need to design your app in such a way that it is tolerant to these lifecycle events, and doesn't need to be kept around forever.
AFAIK, a service or an activity can not be guaranteed to run all the time. You have to handled the lifecycle events of the service like shutdown and start.
My situation:
I have created an Android service, which is started when the app is started. The service consists of a simple Thread that waits for 5 seconds, writes a log message and waits again.
After closing the application (using the back button), Android chooses to restart my service , because I am returning START_STICKY in OnStartCommand.
When debugging the application, I can actually use DDMS to kill the process. Android again chooses to restart the service. This is expected as per the manual.
I also installed a task manager, and used that to "kill" the instance. Funky thing, is that now my service is no longer restarted.
The funky thing is this: in either case, no destroy code of my classes is called. No InterruptedException is raised on my waiting threads. There seems to be no way for my application to know it's being destroyed.
My question:
How can I get around this, and respond to kill requests? I already noticed that the DVM lacks sun.misc.Signal and sun.misc.SignalHandler for proper signal handling (if that's even being used by task killers).
I kind of need to know wether my app is being destroyed, so I can properly close file handles, database connections and the likes.
Many thanks for any assistance.
How can I get around this, and respond to kill requests?
You don't. OTOH, this task killer behavior should have been eliminated in Android 2.2, so it eventually will not be a problem.
My app runs a geolocalisation service that the user can active or disactive by a toggleButton. To check the status of the service, I write a boolean in the Shared Preferences. I listen the beginning of the service and the end of it thanks to the onDestroy() of my service.
My problem is that: When the user kill the service with the "advanced task killer", I can't know that the service is killed, the onDestroy is not called !
How can I deal with that?
Thanks for your help.
Florent
When a process is killed (using ATK or android's own force stop button, or the function here), it is immediately purged from memory (if the kernel allows it). This means there's no chance for any additional code to run, meaning there is no way to really deal with a "force kill" sent to your application.
If you want to handle this, you have 2 options (that I can think of):
Publish a disclaimer telling users to add your app to the "ignore" list of ATK.
Find some way to maintain functionality without relying on the onDestroy() method.
EDIT:
If you want to check for your process from a list of currently-running processes, look into getRunningAppProcesses().
onDestroy()
If you want to restart the service, you can restart in onDestroy().