Notifications
Article
Android quick win: Suspend app into background
Published 8 months ago
68
0
A short discussion on suspending a Unity Android game into background rather than closing it
Typically, the user expects to be able to quit and close an application on his phone by pushing the (hardware) back button (possibly and / or menu navigation). In some situations however, it may make sense to actually prevent this behavior and instead only suspend the app into background.
Note: This article is written for Unity 2017.2.

Pros and cons

Putting an app into background on Android has these effects when compared to a “proper” application shutdown:
  • It gets out of the way of the user (effectively the same as if it was completely closed).
  • It remains in background, consuming a fixed amount of storage and a typically very low amount of battery power.
  • The entire app state is kept in memory as if the app was paused and can be retrieved simply by activating the app again. No explicit logic for scene saving / loading is needed.
  • The app gets reactivated almost immediately, presenting its original state again. There’s also no loading screen.
  • For the user, there’s actually no difference between starting a new instance of an app or reviving an app from its suspended state. The OS will choose the appropriate action when the user clicks the app icon.
These last three points make this an interesting option for app developers. These benefits however come at the price denoted in point 2: memory and (only in theory) battery consumption, which has to be carefully evaluated.

An example app

Let me introduce a simple example app which illustrates a possible use case for the “suspend to background” strategy.
It’s a simple “bubble wrap” mini-game which you can find on Google Play app store here. In this app, the actual default behavior of the phone’s back button is in fact implemented to suspend the app into background, mainly for two reasons:
  • We don’t actually want the user to quit a game before it is finished. In the example app, mimicking a real “bubble wrap” the thinking behind this is that the user can put a warp away and continue it later. In a real-world bubble wrap, it would be rather illogical to throw away an unfinished bubble wrap, only to later grab a new one and start all over again.
  • This could of course also be achieved by actually quitting the app, but saving / loading the application state (e.g. to PlayerPrefs) on quit / startup. Just suspending the app into background is a neat way to basically get the same functionality for free, without any additional coding.

In code

The solution to put an application into background is explained in this Unity Answer:
public class AndroidSuspendOnBackButton : MonoBehaviour { void Update() { if (UnityEngine.Input.GetKeyDown(KeyCode.Escape)) { SuspendToBackgroundOnAndroid(); } } private static void SuspendToBackgroundOnAndroid() { AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"). GetStatic<AndroidJavaObject>("currentActivity"); activity.Call<bool>("moveTaskToBack", true); } }

Tweaking the strategy

Depending on the nature of your app and what specific goal you want to achieve by putting it into background, you may implement a slightly modified version of this app-suspension strategy.
Usually, it would be nice to let the user know (or actually decide) whether the app is really closed or just moved into background.
In the example app, because the impact of running this minimalistic app is so small, I’ve made it so that the app is suspended if the user has actually changed the application state since startup (“popped a bubble”), but it is closed if the app is still in its unchanged startup configuration.
Because suspension of the app state is inherently not safe (see below), you may also go for a two-sided approach: Save the app state properly (e.g. in PlayerPrefs), then suspend the app. When reactivating, test whether the app has been reactivated or newly-started and only load the state from permanent storage if it has been newly-started. The benefit is that if reactivating the app worked, the user doesn’t have to go through the whole startup / loading process, instead the app gets reactivated immediately.
Testing whether an app has been reactivated or newly-started can be as simple as using a boolean flag:
public class InAndroidBackground : MonoBehaviour { private static bool started; void OnApplicationPause(bool paused) { if (!paused) { if (started) { // TODO Application was reactivated } else { // TODO Application was newly started } } started = true; } }

Know the costs

The good news: Battery consumption for a Unity app put into background (rather than quitting it) seems to be a non-issue. In fact, you may even save a bit of battery power as you don’t have to go through the saving / startup / loading process.
You may however want to test the amount of memory taken up by the app when its state is put into stasis. This highly depends on your app’s complexity.
As mentioned earlier, it’s worth noticing that putting an app into background is in no way a “safe” measurement to freeze its state for later reactivation in that the user may (even unintentionally) remove the app from the phone’s memory, e.g. by restarting the phone or by explicitly killing the background process. For serious load / save functionality, you cannot rely on this strategy.

Conclusion

Suspending a Unity app into background on Android is a very simple alternative to the usual save / quit / startup / load cycle. If used properly, it can save development time and make the app more responsive. It is, however, not a valid replacement for classic save / load mechanics.

As a personal remark, this is the first article I’ve written here on Unity Connect. I hope you found it interesting or even useful! Please let me know your thoughts in the comments section.

Nicolas
Software Developer - Programmer
2
Comments