7

I'm writing an app which has a long-running service.

I've written some state-saving code in the service's onDestroy method.

My intention is that this should be invoked if the service ever gets killed by Android, due to memory pressure.

How can I simulate the service being killed by memory pressure?

I've tried adb shell am force-stop com.example.app but the service's onDestroy method was not invoked.

Is onDestroy a sensible site for service-shutdown-state-saving?

If so, how can I make a service's onDestroy be invoked by Android, for debugging/testing purposes?

fadedbee
  • 42,671
  • 44
  • 178
  • 308
  • "How can I simulate the service being killed by memory pressure?" -- a service is never "killed by memory pressure". The entire process is terminated due to memory pressure. Whether that triggers `onDestroy()` or not depends a bit on environmental considerations. "how can I make a service's onDestroy be invoked by Android?" -- call `stopService()` from your test suite, with an `Intent` identifying your service. – CommonsWare Sep 16 '15 at 20:17
  • @CommonsWare "Whether that triggers onDestroy() or not depends a bit on environmental considerations." If `onDestroy` is not always called, where should I site the state-saving code? – fadedbee Sep 16 '15 at 20:18
  • 3
    "If onDestroy is not always called, where should I site the state-saving code?" -- at the point when the state changes. – CommonsWare Sep 16 '15 at 20:20
  • I have seen a similar solution here - http://stackoverflow.com/questions/3117095/stopping-an-android-app-from-console Also, I guess none of the method will be executed when the app crashes so you can handle it in an uncaught exception. Refer this http://stackoverflow.com/questions/19945407/can-i-call-a-method-before-my-application-go-to-crash – Techidiot Sep 16 '15 at 20:21

3 Answers3

10

You should not rely on onDestroy() because it only gets called, when service is properly stopped (by calling stopService() or stopSelf() method).

If you want to save service state, you should either save it as you go (for instance a player service can store it when play/pause function is activated), or use a timer to save it periodically.

If you want to react to memory events, you should use ComponentCallbacks2 class, which will notify you, when Android needs more memory. If you free memory inside those callbacks, you will increase probability your service will stay in memory longer.

Hope this helps.

sergej shafarenka
  • 20,071
  • 7
  • 67
  • 86
1

If you want to programmatically stop your Service, within the Service, call stopSelf().

Alternatively go to the app settings and do a force stop.

akodiakson
  • 779
  • 1
  • 5
  • 10
1

A force stop will not call onDestroy on any components, neither service nor activity. It completely closes the app without any further considerations.

I'm not sure about this but if your service isn't running as foreground service you can close it by removing the app from recent apps menu.

Navid Eivazzadeh
  • 337
  • 3
  • 13