Tuesday, April 9, 2013

Android - When a process gets killed.

According to http://developer.android.com/guide/components/processes-and-threads.html,
the Android OS weighs the relative importance of processes to the user to determine which process is candidate for killing, if system resource (like memory) gets low.


For example, if a process has no visible activity running, it is than assumed to be less important to the user and so likely to get killed, when necessary. So depending on the state of components within a process, the OS makes a decision upon it to kill.

The theory is that Android OS tries to maintain a process as long as possible, but eventually needs to remove or kill old processes to reclaim system resource for a more important process. So the OS somehow holds a list of processes based on importance of components and the state of the components. And so a process with the lowest priority gets killed first and than next and next...

There seems to be 5 levels of importance:


1. Forground process

  •     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.

2. Visible process

  •     It hosts an Activity that is not in the foreground, but is still visible to the user (its onPause() method has been called). This might occur, for example, if the foreground activity started a dialog, which allows the previous activity to be seen behind it.
  •     It hosts a Service that's bound to a visible (or foreground) activity.

3. Service process

  •     A process that is running a service that has been started with the startService() method and does not fall into either of the two higher categories. Although service processes are not directly tied to anything the user sees, they are generally doing things that the user cares about (such as playing music in the background or downloading data on the network), so the system keeps them running unless there's not enough memory to retain them along with all foreground and visible processes.
   
4. Background process



  •     A process holding an activity that's not currently visible to the user (the activity's onStop() method has been called). These processes have no direct impact on the user experience, and the system can kill them at any time to reclaim memory for a foreground, visible, or service process. Usually there are many background processes running, so they are kept in an LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. If an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state.
5. Empty process


  •     A process that doesn't hold any active application components. The only reason to keep this kind of process alive is for caching purposes, to improve startup time the next time a component needs to run in it. The system often kills these processes in order to balance overall system resources between process caches and the underlying kernel caches.
   
But what if you want your service not to be killed by the OS, well there is a trick for that.
To do this, you need to call startForground() method of the Service. You have to pass a notification ID and a notification object. Like this:

startForeground(NOTIFICATION_ID, mNotification);
 

This tells the OS not to kill the service, though the OS will kill it in extreme situation. You can image that when you're listening to music, you don't want the OS to disrupt the music for some reason.

NSNotification example