Unity Android Suspend/Resume and Quit behaviour

Can someone explain (or point me to a document explaining ) the Suspend/Resume, Focus/Unfocus and Application Quitting flow for a Unity android application?

What I’m trying to do is detect when the user pauses or quits my app, and save their data so they can resume from the same place later.

From my experimentation, I’ve found that iOS apps behave in the way you would expect; OnApplicationFocus and OnApplicationPause are called at appropriate points when the app is put into the background and resumed, and OnApplicationQuit is called when the user kills the application.

However Android apps behave in a significantly different fashion;

  1. Application Starts
  2. OnApplicationFocus(true) is called (Gain focus)
  3. User presses the Home or Running Apps button which puts the current app into the background
  4. OnApplicationPause(true) is called (Pausing)
  5. User selects the app from the background apps menu to make it the current app again
  6. The app re-starts entirely, rather than resuming from where it left off, as if the user had booted it for the first time
  7. The user presses the power button to turn off the screen
  8. OnApplicationPause(true) is called (Pausing)
  9. OnApplicationFocus(false) is SOMETIMES called (Lose focus)
  10. The user presses the power button to turn on the screen again
  11. OnApplicationFocus(true) is SOMETIMES called (Gain focus) (if focus was previously lost)
  12. OnApplicationPause(false) is called (Resuming)
  13. The user kills the app from the running apps menu
  14. OnApplicationQuit() IS NOT CALLED

Is this expected behaviour? It seems as though, on Android, apps are never really in the background, since they have to restart each time the user “resumes” them. The puzzling one is why OnApplicationQuit is never called. Is the only way around this behavior to save the game each time OnApplicationPause(true) is called and load up the most-recent save data each time the application boots?

Well, the Android system has a quite complex system for managing apps in memory. The point “6” is not true unless the OS has decided it needed the memory and kicked your app out of memory. In this case your App has to restart entirely, yes. If it’s still in memory you can resume where you left the game.

When you press the power button the app usually should not loose focus and therefore “OnApplicationFocus” is not called. When the user turns the device back on your app should still have the focus.

AFAIK “OnApplicationQuit” is only called on Android when you specifically quit the App via Application.Quit(). Calling Application.Quit will throw the app out of memory manually. I haven’t tested this recently but it used to be that way.

Some people are confused by Androids “recent apps” screen. This screen simply contains “recent apps”. Some apps might still be in memory and can be resumed, others might have been killed already and have to be restarted if you select it. The OS can decide on it’s own when it kicks an app out of memory. This can happen to any app that is in the background at any time. Usually the OS has to free some memory when you start another app that requires the memory.

So whenever “OnApplicationPause(true)” is encountered you might want to store your state. The app might get killed in the meantime.

When your app starts up you want to check your stored state if you can resume the game. Likewise when OnApplicationPause(false) is encountered you also want to resume the game.