I am working on an Android application that collects sensor data over the course of multiple hours. For that, we have a Service that collects the Sensor Data (e.g. Acceleration, GPS, ..), does some processing and stores them remotely on a server.
Currently, this Service runs in a separate process (using android:service=":background" in the manifest). This complicates the communication between the Activities and the Service, but my predecessors created the Application this way because they thought that separating the Service from the Activities would make it more stable.
I would like some more factual reasons for the effort of running a separate process. What are the advantages? Does it really run more stable? Is the Service less likely to be killed by the OS (to free up resources) if it's in a separate process?
Our Application uses startForeground() and friends to minimize the chance of getting killed by the OS.
The Android docs are not very specific about this, the mostly state that it depends on the Application's purpose ;-)
TL;DR What are objective reasons to put a long-running Service in a separate process (in Android)?
Reduced RAM Usage
The Android developer documentation suggests this might be appropriate to keep the service's RAM usage down.
From Managing Your App's Memory: Use multiple processes:
So running the service in a separate process could consequently reduce performance impact of the app while also reducing the likelihood of the service being killed when the system is low on RAM.
Reduced Performance Impact
From Managing Your App's Memory: Switching Apps:
Reduced Likelihood of Being Killed
From Managing Your App's Memory: Release memory as memory becomes tight:
So your service is less likely to be killed when it's in a separate process since the process's RAM usage will be smaller since the service isn't sharing UI resources.
When to do this
If your service doesn't use
startForeground()
, I've found that Android will just kill it when it needs to free up RAM, so the service's RAM consumption isn't too important. So if you're just considering the performance impact on the OS and other apps, I don't think it's worth running the service in a separate process.However, if you do use
startForeground()
, Android will try to keep your service alive as much as possible, so any RAM that the process uses will impact the OS and other apps. So in this case, I recommend using a separate process, which could save at least 10MB of RAM, so you don't slow down your users' devices.Also, note that making your app multi-process is not easy; Android's
SharedPreferences
doesn't support multiple processes. I've made a multi-processSharedPreferences
implementation in one of my projects, but I haven't yet published it for reuse.Separating the service to run in a different process doesn't make it more stable, but in some cases, makes your application more stable, since if this service crashes, your application will not crash with it, and can recover.
Eli
The first place to start is by reading through the description of component lifecycles. The take away from that is you really are not guaranteed that a
Service
or other component will be allowed to run for a long period of time.However, it does sound like a
Service
is the right choice for the functionality you describe. This is because you are doing some operations that are not user facing. Going back to the lifecycle description, any time an Activity is not in the foreground, it is essentially a candidate for being killed.What you should consider doing is using AlarmManager to periodically trigger your
Service
. You might want also to look at using the WakefulIntent library that @CommonsWare has created.There is a good article describing multitasking and processes on the Android blog called Multitasking the Android Way that might get at some of the more details regarding processes you are interested in. For example:
Running a service in its own process has the small advantages that the garbage collector for the service does not affect your application and that the memory footprint of the service is a bit smaller if it runs alone.
If consumption of the service by other applications is not a requirement for you, prefer a local service. Alternatively you can still run the service in its own process and use different communication with your application, e.g. via a broadcast receiver. See Android service tutorial for details.