33

onDestroy() is not always called. If called, only part of the code is executed. And most of the time in LogCat I only see the message "gps state on destroy called first". Why is that?

protected void onDestroy() {
    super.onDestroy();
    Log.d("on destroy called", "gps state on destroy called first");

    editor.putBoolean("gpsOn", false);
    Log.d("on destroy called", "gps state on destroy called second");
    editor.commit();

    Log.d("on destroy called", "gps state on destroy called third");
    stopRouteTracking();
    Log.d("on destroy called", "gps state on destroy called  fourth");
}
Karl Richter
  • 6,271
  • 17
  • 57
  • 120
ksu
  • 812
  • 1
  • 11
  • 17
  • 1
    Have you tried putting this code on `onStop` instead of `onDestroy`? `onStop` is called right before `onDestroy`. And, also, `onDestroy` shouldn't run codes that might take a lot of time. – Hugo Hideki Yamashita Aug 21 '13 at 15:38
  • http://developer.android.com/training/basics/activity-lifecycle/index.html Check the Activity Lifecycle from the Official Docs – Pavlos Aug 21 '13 at 15:38
  • @HugoHidekiYamashita, I haven't try to put it on onStop. I will try it and remove the stopRouteTracking() to see how it work. – ksu Aug 21 '13 at 15:59
  • @Pavlos, from the official doc, there's :Note: do not count on this method being called as a place for saving data! so I think onDestroy() is not called every time. – ksu Aug 21 '13 at 17:05
  • That's what everyone said here! – Pavlos Aug 21 '13 at 17:10
  • Can any one tell me what to do if ondestroy and onstop r not reliable? – Essam Mahdy Jun 28 '18 at 22:13
  • move `super.onDestroy()` to the last line of the method. – Pierre Jan 28 '19 at 11:14

3 Answers3

23

Take a look at this:

Activity OnDestroy never called?

And this:

http://developer.android.com/reference/android/app/Activity.html#onDestroy%28%29

Basically, there's never a guarantee that onDestroy() will be called, and in some cases processes such as your app will be killed directly, bypassing the method call anyway.

Community
  • 1
  • 1
Chris
  • 809
  • 6
  • 16
  • However, why when onDestroy is called, only the first couple of lines are executed. – ksu Aug 21 '13 at 17:15
  • 2
    I can only speculate that the lines beyond the first LogCat might be throwing an exception, but I don't know what the rest of the log looks like. – Chris Aug 21 '13 at 18:10
  • `onStop()` is not guaranteed to be called, either: http://developer.android.com/reference/android/app/Activity.html#onStop%28%29 – ban-geoengineering Feb 24 '16 at 19:51
  • @ban-geoengineering For practical purposes (the overwhelming majority of the time), however, it's safe to assume onStop() will be called as expected, correct? – Kartik Chugh Aug 07 '16 at 17:26
  • @Kartik Chugh Can you post more info about that as this activity lifecycle diagram -https://developer.android.com/images/activity_lifecycle.png - shows an app process can be killed straight after `onPause()` - ie, without `onStop()` (or, therefore, `onDestroy()`) being called. – ban-geoengineering Aug 08 '16 at 16:23
  • 1
    @Ksu `editor.commit()` is a blocking call that accesses the storage. Therefore, it might be long enough for the system to stop waiting and kill your app halfway through onDestroy. I suppose that `stopRouteTracking()` was the missing call? – JM Lord Dec 21 '16 at 21:29
13

In the android developer documentation here, you can see that -

for those methods that are marked as being killable, after that method returns the process hosting the activity may be killed by the system at any time without another line of its code being executed. Because of this, you should use the onPause() method to write any persistent data (such as user edits) to storage.

and onStop() and onDestroy() both are marked as killable.

This may be the reason that only part of the code written in onDestroy() is being called since process can be destroyed at any time after it executes onStop().

Karan
  • 306
  • 2
  • 6
0

@Chris's answer is correct, however your issue where only part of your code is called can arise from the call to super.onDestroy() before calling your code. super.onDestroy() should be called at the end because then your code will be called before it is destroyed.

HaydenKai
  • 759
  • 6
  • 24