Is an android service guaranteed to call onDestroy()? - android

The life cycle diagram of an Activity on an android does not guarantee that onDestroy() would be called, but that the process may be killed and the Activity is removed abruptly. The life cycle diagram of a Service on an android does guarantee that onDestroy() would be called. So I have two questions relating to this difference.
Firstly, if the Service is part of the same process as the Activity, is the Service onDestroy() called, though the Activity onDestroy() is not called? I would think not, as "killing a process" suggest that the operating system is stopping its threads and releasing its resources.
And if that is the case, can a Service-only-process be abruptly killed by the OS?

I'm not sure where you're seeing that a Service is guaranteed to have onDestroy() called. As far as I know, this isn't the case. If you read this page of the docs, it describes the conditions in which a service could be killed. So if you're asking if a process which hosts both an activity and service is being killed, will onDestroy() be called on the service (but not on the activity) then the answer is no; a service's onDestroy() will not necessarily be called. As to whether a service-only process can be abruptly killed by the OS: yes, it can. This is especially true when you have a lot of work to do, and your onStartCommand call only queues up the work to do asynchronously. Then the service will be spending the majority of its time not in the protected onCreate, onStartCommand or onDestroy methods.

There are two things to consider:
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. Source
In this case onDestroy() is not called as the Android OS will reclaim resources anyway (this is a basic task of the OS in general).
A service can be both started and have connections bound to it. In
such a case, the system will keep the service running as long as
either it is started or there are one or more connections to it with
the Context.BIND_AUTO_CREATE flag. Once neither of these situations
hold, the service's onDestroy() method is called and the service is
effectively terminated. All cleanup (stopping threads, unregistering
receivers) should be complete upon returning from
onDestroy(). Source
So when the Android OS notices that the Service has finished its job and is not needed anymore it will be destroyed. The OS gives the app a chance to release the Service's resources to prevent memory leaks. In this case onDestroy() is called as this is the place where the app can release its resources. Of course in this case the application's process stays untouched (as there may be other Services/Activities running in it).

Related

Android - Ensuring that Wakelock is released when a Service's process is killed by OS

I want my FusedLocationProvider to ping for location even when the screen is off. For this, in my service, I have a PARTIAL_WAKE_LOCK, to keep the CPU running and to ensure that the service continues to run even when the screen is off.
That being said, I know the Android OS will kill off services/apps in the background when it needs memory. Due to this, my service can be killed off.
When this happens, onDestroy() in the Service is not guaranteed to be called. If that is the case, how do I ensure that the WakeLock gets released?
I call mWakeLock.acquire(); in onStartCommand, and in onDestroy I call mWakeLock.release();
how do I ensure that the WakeLock gets released?
According to the docs:
If the service is currently executing code in its onCreate(),
onStartCommand(), or onDestroy() methods, then the hosting process will be a
foreground process to ensure this code can execute without being killed.
What this means is that if the code in any of those methods is currently being executed, then the process won't be killed (or at least will be given a very high priority) till the code finishes executing.
However, the short answer to your question is that there is NO way to ensure that onDestroy() or onPause() gets called. onPause(), though, does have a far greater probability of getting called, so you could look into that. There is also a method, Application.onTerminate() which you may want to use for further research on this. The method is only called when running the app on emulators.
I don't think you need to worry about a memory leak, though (assuming that we are both on the same page regarding what such a leak constitutes). When a process is killed, the memory is reclaimed by the kernel, not by the GC, so there isn't going to be a memory leak in that case.
EDIT:
I have confirmed that if a process is killed, an acquired wakelock will necessarily be released:
1. Does the android os release a wakelock if the app or service holding it is killed ?.
2. What happens with the partial wake lock if the process that acquires is killed ?.
3. Binders & Death Recipients.
4. How to deal with (orphaned) WakeLocks?.

onDestroy() in Android service

I have 2 questions regarding the onDestroy() method of a service
1.Will the onDestroy() method of a service be called if the service is killed by the system because of lack of memory.
2.Will the onDestroy() method of a service be called if the service is killed because the app that started the service was swiped away by the user in the resent apps screen.
When the service is terminated by system onDestroy will be called, but when your application process is terminated onDestroy may not be called.
onDestroy() will be called IF service is being terminated as a result. (this is not always the case) See this discussion for more info.
First question.
Based on my previous experience and Android dev docs.onDestroy() method of a service is called even if the service is killed by the system.Google Android dev documentation is belowe.
A service can be both started and have connections bound to it. In
such a case, the system will keep the service running as long as
either it is started or there are one or more connections to it with
the Context.BIND_AUTO_CREATE flag. Once neither of these situations
hold, the service's onDestroy() method is called and the service is
effectively terminated. All cleanup (stopping threads, unregistering
receivers) should be complete upon returning from onDestroy().
Second question.
If you would like to kill service when you close your app so yes. Aneroid services are running on the background and normally are not killed when you destroy you're app.

is it really wrong to release resources in onDestroy?

Android documentation says (in http://developer.android.com/training/basics/activity-lifecycle/stopping.html):
In extreme cases, the system might simply kill your app process without calling the activity's final onDestroy() callback, so it's important you use onStop() to release resources that might leak memory.
Sounds like it is wrong. How could killed process leak memory?
Suppose you started a service in your onStart() method, and you intend to stop that service when the user gets out of the Activity.
If you put the code to stop the service in onDestroy(), that code may never get called, which can leave that service running until Android decides to kill it (which may not happen for a while, if ever). That running service is and example of leaking memory/resources outside your application.
You should put cleanup code like that in a method that is guaranteed to be called.
Note that a process is killable after onPause() has been called, so onPause() is really the place you want to do cleanup that absolutely must happen.
(See table 1 in https://developer.android.com/guide/components/activities.html for details on the Activity lifecycle)
Another thing that might be really bad to leak: Bluetooth discovery or location reporting (GPS or network-based) turned on but not off as soon as possible - very bad for battery life.

If android restarts a Service is onCreate called again?

From my little android knowledge I understand that android OS can kill my service under extreme memory conditions.
I have created a service that returns START_STICKY. The service is meant to run in background.
If android is about to kill my service, will it call onDestroy ?
And when it restarts it would it call onCreate ?
See here, the dev guide. http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle
onCreate() is only called when the process starts, which can either be the first time the service is running, or if it was killed on restarted, essentially this is called whenever it starts.
onStartCommand() is called whenever a client calls startService().
When a service is destroyed / completely stopped, Android is supposed to call onDestroy() on that service. I think it's possible for that to not happen (e.g. process is killed not through Android system). In the case of a bound service, this is when there are not more active client binders.
Edit: onCreate() Service starts; onStartCommand()someone uses service; onDestroy()Service is killed / stopped.
If someone calls Context.startService() then the system will retrieve
the service (creating it and calling its onCreate() method if needed)
and then call its onStartCommand(Intent, int, int) method with the
arguments supplied by the client
...
A service can be both started and have connections bound to it. In
such a case, the system will keep the service running as long as
either it is started or there are one or more connections to it with
the Context.BIND_AUTO_CREATE flag. Once neither of these situations
hold, the service's onDestroy() method is called and the service is
effectively terminated. All cleanup (stopping threads, unregistering
receivers) should be complete upon returning from onDestroy().
http://developer.android.com/reference/android/app/Service.html
EDIT: Quick answer. Yes to both questions

Will we leak the android service connection if the client's process is killed by android?

Condition:
I have a client activity "X" of a remote service (with AIDL) that calls the bindService() in the onCreate() and unbindService() in the onDestroy(). Assume that this activity has been started but not in the foreground (onStop() has happened).
It is said that when android system needs more memory elsewhere it might kill the process of another activity with less priority (possibly "X").
If, says, the android system decides to kill "X"'s process, according to the activity-lifecycle diagram the onDestroy() will not be called if the process is killed when more memory is needed.
http://developer.android.com/guide/topics/fundamentals/activities.html
Question:
Will this cause it to leak the service connection? Is it safer then to bind and unbind service in onStart() and onStop()?
Thanks in advance!
Question: Will this cause it to leak the service connection?
The ServiceConnection object would be in the process of "X" and therefore will go away when that process is terminated.

Categories

Resources