Effect of swiping an Android app in recent app list
Published on :
By nature, an Android app can be stopped and killed any time by the user or the system. The system can decide to kill an app to free some memory. It is also very easy for the user to display the recent app list and to swipe an app, thinking he kills the app by doing so.
Contrary to iOS, Android allows running some background tasks through Services; knowing the effects of an app swipe on services is important to correctly implement apps’ services.
What exactly happens after a “kill” initiated by the user? How can we react and protect the execution of a background service? Android provides tools to give some priorities to services, but what exactly happens to the lifecyle of the app hosting the service?
We concentrate on kill initiated by a swipe in the recent app list. It is also possible to kill an app using the hidden developer menu in the settings, but it is dedicated to developers and it effectively completely kills an app and its services.
Experimentation on Services
We create 3 main classes:
MyApplication
to monitor when an application is completely recreated; it inherits from theApplication
classMyActivity
to launch a service, our mainActivity
MyService
to monitor when a service is destroyed by the system
Each class has some logs displayed in Logcat. For each app:
- the app is launched
- the recent app list menu is triggered and the app is swipped
- the app is then manally launched again
Logs are collected and studied.
MyApplication
does not vary from a test to another. The first implement of
MyActivity
is common to several tests. Here are their implementations.
Code is available on GitHub.
MyApplication.java
MyActivity.java
START_NOT_STICKY service
In this test, we create a service in START_NOT_STICKY
mode. This is the
simplest of all test cases.
MyService.java
- App launch
- App swipe
The app is completely stopped. It is launched again, we have the same logs than in step 1.
Conclusion: the app is simply and completely killed.
It is interesting to note MyService.onDestroy()
is not called. Actually, you
must explicitely called MyService.finish()
if you want to be sure
onDestroy()
is called. Another way to be sure this method is called is to
manually kill the app in the hidden developer menu in Android settings.
START_STICKY service
By using the START_STICKY
mode, we directly ask the system to recreate the
service if it is killed. But how does it exactly work?
We write the following modification in the MyService
class.
- App launch
- App swipe
The previous process is killed, but a new one is then immediately launched.
Conclusion: the app is completely destroyed, and then completely recreated. No Activity is called, but the Application class is recreated before respawning the service.
So be sure to correctly intialize what the Service needs in the Application class, not in the main Activity class.
startForeground service
Here, we explicitely tells the system the service is important and must not be
considered as a background task that can be killd anytime. Actually, it is
mandatory to provide a Notification
object, so the user is explicitely warned
that his app stays alive.
We write the following modification in the MyService
class.
- App launch
- App swipe
Even if onTaskRemoved()
is called, the app is not killed in this case.
The service continue to exist. It can be proven by going to the hidden developer
menu to check running processes.
- New app launch
Neither the MyApplication.onCreate() method nor MyService.onCreate() are called. Actually, the app was never killed.
Conclusion: this case is a very good candidate to make a service persist in case of a manual kill by the user. The app and the service are never killed: only the Activity (usually the visual part) is destroyed from memory.
Be careful to the lifecycle of the app: a new Activity is recreated when the app
is launched again, but the MyApplication
object is not recreated and was never
destroyed.
Diagram summary
A service can always be destroyed due to low memory or manual killing through the hidden developer menu, so it is a case to be taken into account anyway.
So far, the startForeground
mechanism seems the best since it protects an
app to restart, contrary to the START_NOT_STICKY
method.
Beware of the cases where the Application
class is called or is not called.