47

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)?

Michael Kohne
  • 11,888
  • 3
  • 47
  • 79
pableu
  • 3,200
  • 4
  • 23
  • 21
  • 3
    I think you meant android:process=":background". The big reason we separate services from activities is to prevent the dreaded ANR (activity not responding). The drawbacks are IPC becomes a little trickier and the overhead of an additional process. – phreed Feb 25 '11 at 14:19
  • 1
    Note that closing an application by swiping it away at Recent applications also kills the service even if it runs in a separate process. This greatly affects apps that run external programs in their service. (observed with Android 4.3.1, seems "by design" according to #android on Freenode.) – Lekensteyn Nov 27 '13 at 17:51
  • @Lekensteyn, that hasn't been the case for me with my Sony Xperia M running Android 4.3, 5.0 & 5.1. What model is your device? Maybe this is implementation-dependent. – Sam Jun 02 '15 at 22:34
  • @sam this was probably a Samsung Galaxy S3 (i9300) running CyanogenMod. – Lekensteyn Jun 03 '15 at 00:11
  • @Lekensteyn, I recently noticed that this behaviour occurs if the activity that you're killing has ever bound to the service or another service in the background process. – Sam Jun 16 '15 at 12:07
  • 1
    @Lekensteyn any idea on how to keep the service running even after the user swipes it away? Keep it running; not restart – Zen Mar 06 '16 at 22:57
  • @Sam & Lekensteyn In my case when i swipe away the application from apps panel, my service get restarted which ends up current task and then restarts. (Irrespective you run service in different process or not and irrespective of device model and OS). Do you guys have any solution for that (avoid restarting of service on swiping away). Thanks in advance! – Farhan Nov 09 '16 at 13:52
  • @Farhan, there's no easy solution, but there are some workarounds you can combine to get it all working. I just wrote them up in [this answer](http://stackoverflow.com/a/40515935/238753). – Sam Nov 09 '16 at 21:00

4 Answers4

25

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:

An example of when multiple processes may be appropriate is when building a music player that plays music from a service for long period of time. If the entire app runs in one process, then many of the allocations performed for its activity UI must be kept around as long as it is playing music, even if the user is currently in another app and the service is controlling the playback. An app like this may be split into two process: one for its UI, and the other for the work that continues running in the background service.

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:

If your app has a cached process and it retains memory that it currently does not need, then your app—even while the user is not using it—is constraining the system's overall performance. So, as the system runs low on memory, it may kill processes in the LRU cache beginning with the process least recently used, but also giving some consideration toward which processes are most memory intensive.

Reduced Likelihood of Being Killed

From Managing Your App's Memory: Release memory as memory becomes tight:

Note: When the system begins killing processes in the LRU cache, although it primarily works bottom-up, it does give some consideration to which processes are consuming more memory and will thus provide the system more memory gain if killed. So the less memory you consume while in the LRU list overall, the better your chances are to remain in the list and be able to quickly resume.

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.

Sam
  • 40,644
  • 36
  • 176
  • 219
22

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:

A common misunderstanding about Android multitasking is the difference between a process and an application. In Android these are not tightly coupled entities: applications may seem present to the user without an actual process currently running the app; multiple applications may share processes, or one application may make use of multiple processes depending on its needs; the process(es) of an application may be kept around by Android even when that application is not actively doing something.

Eric Levine
  • 13,536
  • 5
  • 49
  • 49
  • 1
    Thanks for your thoughts. I've already read the lifecycles description (multiple times), and I am aware that there are no guarantees. But I'd like to know more exactly why/how a separate process could be of advantage, and for example how exactly the OS decides which processes to kill (the documentation only seems to give a few examples of what's "important"). Could I use the WakefulIntent to restart my Service if it's been killed by the OS? That would be pretty neat ;-) – pableu Jan 11 '11 at 15:08
  • 1
    Yes, the AlarmManager or WakefulIntent will start/restart the service if it is not already running. – Eric Levine Jan 11 '11 at 18:31
  • I added a link to an article that might get at the explanation you want regarding processes in Android. – Eric Levine Jan 11 '11 at 23:12
  • 9
    I don't feel like this answer addresses the core question. The OP already has a service and is debating whether it should be a separate process or not. AFAICT, this post doesn't answer that. – Duncan Jones Dec 22 '14 at 08:48
  • @Duncan OP accepted this as the answer, so they must have felt that it did address their question :) – Eric Levine Dec 22 '14 at 17:31
15

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.

vogella
  • 24,574
  • 4
  • 29
  • 26
  • 1
    This answer is more appropriate to the question. Another thing is that when the service crashes, it won't take down your app and vice versa. I communicate via Messenger https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.java and https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.java thanks for your awesome tuts btw. – frostymarvelous Jun 08 '14 at 17:45
9

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

Jeemusu
  • 10,415
  • 3
  • 42
  • 64
Eli
  • 707
  • 8
  • 16
  • Actually, it does make the service more stable, for the same reason in reverse: if the application crashes, the service won't crash with it. – Glenn Maynard Mar 03 '15 at 23:32
  • 1
    If I simulate it using android close application, the application kill will also kill the external process. – Eli Mar 05 '15 at 05:26
  • That's explicitly killing the app, not the app crashing. – Glenn Maynard Mar 05 '15 at 15:51
  • If I remember correctly, when my app (that contained external service) crashed, it also dragged with it the external service (process). – Eli Mar 09 '15 at 12:23
  • I just tested this out and confirmed that, in my case, crashing in the main process didn't affect the service's process. – Sam Jun 06 '15 at 22:35
  • So if I swipe-close the app from recents drawer, the separate process will also be killed? – IgorGanapolsky Aug 29 '17 at 17:20