Many of us know that (in loose terms) a Service
in Android will get killed by the system if it does not call Service.startForeground()
. But is this the whole story...?
I am working on some legacy code, porting a "system" permission app to the Play store. This app has 5 background services (that do not call startForeground()
), which until now, were safe, due to the "system" permission that the app ran with. It was installed on a custom device. Due to tight timelines and budgets, refactoring these 5 into 1 is not a short term solution, but we would like to move to open beta as soon as possible.
The short question is:
- If there is no foreground
Activity
orService
, does Android kill each individual background service, or does it just kill the process itself?
Here is some info from the Android docs on Processes and Threads that discusses how Android will terminate processes when under pressure:
Android might decide to shut down a process at some point, when memory is low and required by other processes that are more immediately serving the user. Application components running in the process that's killed are consequently destroyed. A process is started again for those components when there's again work for them to do.
When deciding which processes to kill, the Android system weighs their relative importance to the user. For example, it more readily shuts down a process hosting activities that are no longer visible on screen, compared to a process hosting visible activities. The decision whether to terminate a process, therefore, depends on the state of the components running in that process. ...
Common knowledge says that "Android will kill the Service"
Personal experience has shown that Android will also kill the process itself (as described in the quote above). This can be shown by storing objects in the Application
object, and noting that they get reinitialised after the service is killed.
With the above in mind, there are a few options for solving the problem:
1) Do the Right Thing
Refactor the 5 services into 1, running on various different threads. Bring the 1 service into the foreground. Problem solved.
Unfortunately no budget for this at the moment, and we would prefer to find a quick fix due to project timelines.
This is the final solution that will be implemented going forwards into full production.
2) Many Notifications
Start each service in foreground, each with its own Notification
icon.
This is a messy solution, but will work for the beta field trials, buying us some time.
I think of this as the "brute force" approach.
3) Process protected by one Service
If it is the process that is killed, rather than each individual service, then it will be good enough to have a single foreground service running.
This would "prevent" (i.e. lower the probability of) Android from killing the process.
All 5 services would thus survive.
4) One Service to rule them all
The docs on Services tell us that if a service is bound to another context, then
stopService() or stopSelf() does not actually stop the service until all clients unbind.
If I bind to the other services from a single foreground service, will that keep them all alive?
So:
- Does Android kill each unbound, background Service?
- Or does it just kill the VM that the application is running in?
Update
After 18 41 hours of testing #3 (Process protected by one Service), all 6 services are still running (5 old plus the 1 new).
So it is looking as if Android would kill the process if no foreground activities or services are running.