Activities in Android/Xamarin.Android are far more than just screens. They are a first-class component of the Android runtime with a distinct lifecycle. An important aspect of that lifecycle is how the Activity behaves when your app transitions away from an Activity and then returns to it.
What Happens When the User Isn’t Looking?
When a user leaves an Activity (we’ll call it Activity-A) to view another Activity, sometimes the Android runtime will simply move Activity-A into the background, in other cases the runtime may destroy Activity-A. When the user returns to Activity-A, if its still running in the background, the runtime simply moves it into the foreground. But … if it was destroyed, the system creates a brand new instance of Activity-A and as developers we’re responsible to be sure that Activity-A is restored to the same state it was in when the user left it.
In other words, it’s our job to put the magic together that creates the illusion that Activity-A has been waiting patiently for the user to return even if that’s not actually the case.
Managing this lifetime correctly can be a bit of a challenge. It means that the state of every member variable must be persisted (normally stored by your Activity’s OnSaveInstanceState method) and then restored (normally handled in your Activity’s OnCreate and/or OnRestoreInstanceState methods). Restoring the Activity means that we must also assure that all of the behaviors dependent on those member variables are restored as well.
Why Does My Activity Only Break in the Field?
When developing and testing our apps, generally the only thing the test device is doing is running our app. This avoids many of the issues (depleting system resources, etc.) that cause the system to destroy an Activity when the user moves away from that Activity. The result is that we end up testing only the most simple case of our application … the Activity being initially created and then continuing to exist until we’re done with it.
However, when our app goes out into the field, it’s facing a much harsher environment. Our real-life users may have many different things running on their phones or maybe they’re using a phone with much more limited resources then our test phones. The in-the-field scenarios significantly increase the likelihood that an Activity will be destroyed when the user moves away from it and then fully recreated when the user returns.
This results in the app encountering scenarios in the field that we may have never experienced during our app development and testing.
Forcing Activity Kills
To assure that our apps work correctly in scenarios where the Activities are destroyed and restored, we must be sure to include that behavior in our app testing.
Under normal Android behavior, testing this case is difficult because keeping or destroying an Activity is something that occurs at the discretion of the Android runtime … what we need to do is get around this normal behavior of the Android runtime.
We need to force the runtime to kill our Activities when we move away from them so that we can verify that our Activities restore themselves correctly.
The Don’t Keep Activities Option
Fortunately, Android provides a series of Developer Options that allow us to alter the behavior of the Android runtime during our app testing. One of those options is “Don’t keep activities”.
As it’s name implies, when set, the runtime does not keep Activities running when the user moves away from them instead Activities are always destroyed.
To access this option, open up your device settings and locate “Developer options”. You’ll probably have to scroll pretty far down to find it.
BTW: Some 4.x versions of Android hide “Developer options” by default. See this post for instructions for unhiding it.
Once your’re in the list of Developer Options, scroll down until you find “Don’t keep activities” (it’ll probably be near the end of the list of options). Select the check mark next to it to enable the option.
And Now We Have Stability
With the “Don’t keep activities” option enabled, you can now fully test your Activities. Every time you move away from an Activity, it will be destroyed. When you return to the Activity, it will then go through its full restoration cycle. You’re now able to consistently test the most challenging part of the Activity life cycle.
Making use of the “Don’t keep activities” option during our testing has been a key part of how we assure that our Spectafy app remains stable in the field. Our users are highly diverse using a wide variety of phones. With the rich nature (maps, lots of images, complex data model) of many of our screens (Here’s just a few of them)…
… we need to be sure that each Activity provides that consistent, stable experience in all scenarios.
To that end, we regularly exercise our app with the “Don’t keep activities” option enabled. This practice allows us to be sure that each Activity correctly restores itself and provides our users with an uninterrupted, stable experience.
I encourage you to incorporate “Don’t keep activities” as regular part of your Xamarin.Android development and testing. (BTW: this option is equally useful for Java-based Android development as well). It’ll make a big difference in the field stability of your apps and help you avoid having to deal with a lot of painful I-can’t-reproduce-the-problem debugging headaches.
The title is a bit misleading here. I would say “Improve Activity State Debugging in Android Apps with Developer Options” or something like that as this is just general Android development and not specific to Xamarin at all. Enabling this option wont increase your stability of your app at all, as it is just used for development testing.
I would link simply to the Activity Lifecycle walkthrough and also the entire guide on how to save and restore your Activity state in Xamarin.Android:
The fact that it’s a testing tool is exactly the point I make in the post … and as a testing tool, it’s hugely useful in achieving greater app stability in the field. 🙂
I also make the point that it’s actually a general Android issue. The following quote comes from the post…
“BTW: this option is equally useful for Java-based Android development as well”.
I will say, though, that as someone who has been an Android developer for a long time now (both as a consultant and as someone who creates training materials) I’m finding that Xamarin developers are being caught by the challenges of the Android Activity lifecycle issues more so than many of the Java-based Android devs I’ve worked with.
Honestly, I think that part of the issue is that Xamarin does such a great job of allowing people to bring their .NET skills to Android that many developers don’t realize that they need to consider some of the larger platform issues (like Activity lifecycle stuff) until it bites them.
With regard to the title, it is chosen partly to be fun but I especially wanted to be sure that it is something that Xamarin developers pay attention to because I’m seeing Xamarin devs run into so many issues with the Activity lifecycle.
I agree with you that the topic can be applied on a larger scale but it is fully applicable and accurate in the context discussed in the post.
Thanks for commenting and for those great links.