BroadcastReceivers and Memory Usage - android

I've not had the time to play with receivers, and also I'm unfamiliar with anything above 2.3.x, so I was totally puzzled when I read this question:
Can BroadcastReceiver registered in AndroidManifest receive intents when application process is killed?
Its author is able to see the BroadcastReceiver application in the task manager list, and when the app is killed, the broadcast receiver no longer is called. This is due to a new mechanism introduced in 3.1:
http://developer.android.com/sdk/android-3.1.html#launchcontrols
In that link, the stopped state for an Application is mentioned. Application lifecycle isn't explained anywhere in the docs, AFAIK, so I guess an App can be in one of these 3 states:
Stopped (not in RAM)
Started (in RAM, not running)
Running (in RAM)
For the user to be able to see the app in the Task Manager, it should be in either started or running state (I'm guessing here, because I don't know if there are more states). And seems that the app was showing in the list for a significant amount of time. If a receiver app is started or running, it must have a linux hosting process with its own Dalvik VM instance. This is in conflict with my previous beliefs on how receivers should work:
When a receiver isn't running, there's no performance penalty to the system.
Once a receiver needs to be notified, a new foreground process is spawned (if not already running), a new Receiver is instantiated, and the onReceive method is called.
After a max processing time of 10 secs, onReceive returns, and provided there are no additional Services or Activities, the hosting process is very likely being killed, thus releasing resources.
So, my questions:
If the app is shown in the task manager (hence there's a process), but hasn't been notified yet, why would the OS spawn a process for a receiver that hasn't even been notified (and might not be notified at all). If the app has been notified but the process hasn't been killed yet, (and so it is listed in the task manager), why doesn't the OS kill it shortly after it completes? Here I'm assuming the task manager only shows an application if it has a process allocated, but this raises the following question:
What are the chances of having a receiver process listed in the task manager? Does the task manager show the receiver app even if it is stopped? If so, is this the new behaviour for 3.1+ so that the user can notice it exists and force-close it? If not, the application should only be listed there if it is in the middle of a call to onReceive or after it returns and is eligible to be killed, which according to the docs, should be a short interval.
Thanks in advance.

so I guess an App can be in one of these 3 states: Stopped (not in RAM), Started (in RAM, not running), Running (in RAM)
Not exactly, at least as how I would phrase it, though that might be a terminology and/or language issue.
A process is either running or not running. It cannot be "in RAM" and "not running".
Independently of this concept, an application can have its manifest-registered BroadcastReceivers be disabled or enabled, as of Android 3.1. The docs refer to the disabled state as "stopped", which is a very unfortunate choice of terms on Google's part, one that I have complained about on several occasions. When you see references to this state, ignore any other definitions of the term "stopped". In fact, you might want to make up some other term for this state, such as "snicklefritzed".
Your app is snicklefritzed immediately after installation. Your app is moved into a "normal" state once something explicitly runs one of your components (e.g., user manually launches an activity from the home screen). Your app is moved back to be snicklefritzed when the user force-stops your app from Settings. The information about whether an app is normal or snicklefritzed is held in some OS-managed file and (AFAIK) is cached in an OS process.
Hence, an application is either:
Not running (no process) and snicklefritzed
Not running (no process) and not snicklefritzed
Running (has a process) and not snicklefritzed
(it is not possible to be running and snicklefritzed, because the act of running something would have moved you out of the snicklefritzed state, and a force-stop would terminate your process)
When a receiver isn't running, there's no performance penalty to the system.
Correct.
Once a receiver needs to be notified, a new foreground process is spawned (if not already running), a new Receiver is instantiated, and the onReceive method is called.
Correct.
After a max processing time of 10 secs, onReceive returns, and provided there are no additional Services or Activities, the hosting process is very likely being killed, thus releasing resources.
I would phrase it as "the hosting process is eligible to be killed and will be relatively high in the priority queue to be killed as the OS needs RAM for other processes".
Why would the OS spawn a process for a receiver that hasn't even been notified (and might not be notified at all).
It doesn't. A snicklefritzed app's manifest-registered BroadcastReceivers are ignored.
What are the chances of having a receiver process listed in the task manager?
100% while the process is running. 0% when the process is not running.
Is this the new behaviour for 3.1+ so that the user can notice it exists and force-close it?
I have no idea what you are referring to when you say "this" and "it".
Or is it the normal behaviour when the system has enough memory available, even for 2.x OSes?
I still have no idea what you are referring to when you say "it".

Related

Android process in background - it must remain always alive - sometimes it has to play sounds [duplicate]

I have a Service running in the same process as my Application.
Sometimes the Android OS decides to kill my service (probably due to low memory).
My question is: does my Application get killed along with the Service? or how does it work exactly?
Thanks!
First be sure to read: http://developer.android.com/guide/components/processes-and-threads.html#Lifecycle
The key to this is that on Android a process is just a container for code -- or specifically one or more components (activities, services, receivers, providers). By default all components in a .apk get their own, dedicated process, that they all run in together. This is almost always what you want.
When the user is directly interacting with a component of that process (that is an activity) Android will try very hard to keep that process running, and you won't see it killed except under extraordinary circumstances.
When the user is no longer directly interacting with the process, then it becomes expendable relative to other processes as described in the referenced documentation. That is, empty processes (no interesting components) will be killed before processes holding activities that the user had been using, which will be killed before processes with running services. So having a running service will tend to keep your process around at the expense of other processes.
At the same time, we need to deal well with more and more applications leaving services running, often indefinitely, and often with memory leaks. So has a service runs for an increasingly long time, Android will try less and less hard to keep its process going. Effectively this means moving it down to the background bucket until the out of memory killer takes it out. After that, if the service still wants to run, then a new process will be created for it to be restarted in.
The upshot is that for normal services that are running a long time, it is expected behavior that their process will get killed after a while. This doesn't need to stop the service; a service that wants to continue running will do so, it will just need to be instantiated in a new process.
Of course as long as the user is interacting with an activity in your process, the process won't be killed, since this pulls it to the foreground category regardless of what is going on with any services in it.
Processes are killed by the low memory killer, not Applications. So unless you do extra work to get your Service running in a different process, then your Activities are killed along with your Service.
The low memory killer doesn't try to destroy any objects in your process, although the activity manager may call onDestroy on Activity objects that are no longer needed. But that happens as part of the regular activity lifecycle, not due to low memory conditions.
(By the way, I'm unclear whether you mean "application" in general, or your object that extends Application, or whether you mean your Activities that show the UI.)
An application is something that has a user interface and if you have included a service along with it, then definitely it will be killed since Applications are terminated once the cached application queue becomes full
so create Service separate from application or in other words create an other project for it :)
btw, i'm not an experienced Android developer but thats i think what i learned by watching the Android development life cycle videos by Google

Android process lifecycle & services

I have been reading about process life-cycles after I noticed that android unexpectedly terminated my app. The app is normally running also in background but now it was terminated. The app listens gps location updates, battery state broadcasts, receives sms broadcasts, runs Bluetooth and tcp server etc. So it has quite a lot of jobs to do and until now it has succeeded pretty well.
What I found out was that android probably closed the process due to low RAM. My app was still in the 'app swap' list but when I selected it I noticed that it was actually restarted which explained the fact that I was not able to connect it earlier using tcp. Do you agree my conclusion or is there any other reason than low RAM that could cause this?
After reading a bit more I understood I should have implemented almost the whole application as a foreground service because those will be killed only after there are no normal activities to kill. However I'm not that comfortable in doing such a bit changes to the application at this point. BUT, then I found this:
http://developer.android.com/guide/components/processes-and-threads.html
There are five levels in the importance hierarchy. The following list presents the different types of processes in order of importance (the first process is most important and is killed last):
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:
-It hosts an Activity that the user is interacting with (the Activity's onResume() method has been called).
-It hosts a Service that's bound to the activity that the user is interacting with.
-It hosts a Service that's running "in the foreground"—the service has called startForeground().
-It hosts a Service that's executing one of its lifecycle callbacks (onCreate(), onStart(), or onDestroy()).
-It hosts a BroadcastReceiver that's executing its onReceive() method.
Please correct if I got the bolded condition wrong. Doesn't it mean that I could just make my app to host a dummy foreground service after which the process running my app and the dummy service would be considered as foreground process which again would mean that it would be very unlike that Android killed my app?? This way I wouldn't have to go through all the functions my app has and to figure out how to get them work as a service.
Thanks!

Does having a foreground Service protect the entire process from being killed?

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.

How and when does a service get automatically restarted in Android

According to the docs (ref: http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle), android will automatically restart a service that is killed due to low memory.
To quote:
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.
My questions are:
(1) How does the system decide which services to restart?
(2) When is "later"?
Processes on the Android work in a hierarchical structure, so whatever services are on the top of the list get restarted first. This also applies to active processes, so if you have a process in the foreground that you are running, that foreground service is at the top of the list and will be removed first. It's pretty much a stack. I think that processes under higher memory pressure are moved up in priority, but who knows, you would have to look at the belly of the beast to see what's actually happening.

Android service killed

I have a Service running in the same process as my Application.
Sometimes the Android OS decides to kill my service (probably due to low memory).
My question is: does my Application get killed along with the Service? or how does it work exactly?
Thanks!
First be sure to read: http://developer.android.com/guide/components/processes-and-threads.html#Lifecycle
The key to this is that on Android a process is just a container for code -- or specifically one or more components (activities, services, receivers, providers). By default all components in a .apk get their own, dedicated process, that they all run in together. This is almost always what you want.
When the user is directly interacting with a component of that process (that is an activity) Android will try very hard to keep that process running, and you won't see it killed except under extraordinary circumstances.
When the user is no longer directly interacting with the process, then it becomes expendable relative to other processes as described in the referenced documentation. That is, empty processes (no interesting components) will be killed before processes holding activities that the user had been using, which will be killed before processes with running services. So having a running service will tend to keep your process around at the expense of other processes.
At the same time, we need to deal well with more and more applications leaving services running, often indefinitely, and often with memory leaks. So has a service runs for an increasingly long time, Android will try less and less hard to keep its process going. Effectively this means moving it down to the background bucket until the out of memory killer takes it out. After that, if the service still wants to run, then a new process will be created for it to be restarted in.
The upshot is that for normal services that are running a long time, it is expected behavior that their process will get killed after a while. This doesn't need to stop the service; a service that wants to continue running will do so, it will just need to be instantiated in a new process.
Of course as long as the user is interacting with an activity in your process, the process won't be killed, since this pulls it to the foreground category regardless of what is going on with any services in it.
Processes are killed by the low memory killer, not Applications. So unless you do extra work to get your Service running in a different process, then your Activities are killed along with your Service.
The low memory killer doesn't try to destroy any objects in your process, although the activity manager may call onDestroy on Activity objects that are no longer needed. But that happens as part of the regular activity lifecycle, not due to low memory conditions.
(By the way, I'm unclear whether you mean "application" in general, or your object that extends Application, or whether you mean your Activities that show the UI.)
An application is something that has a user interface and if you have included a service along with it, then definitely it will be killed since Applications are terminated once the cached application queue becomes full
so create Service separate from application or in other words create an other project for it :)
btw, i'm not an experienced Android developer but thats i think what i learned by watching the Android development life cycle videos by Google

Categories

Resources