Where to hold Global application state in Android apps
May 9, 2012
I recently started working on a project with savvy apps and we came to a discussion about where to handle Global application state – a bit of information that you need to access pretty much everywhere. Here are the options I’ve thought of, and the tradeoffs involved.
Extend the Application Class
You can extend the Application class and add your own fields to the subclass. You specify your class in your manifest file with the android:name attribute without your application node. Then any context (e.g. Activity or Service) that wants to get to this information can call
Context.getApplicationContext() to get your Application object.
This is a reasonable way to store state that you’re okay with losing when the Application is destroyed. The documentation page for Application mildly discourages this use:
“There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a
Contextwhich internally uses
Context.getApplicationContext()when first constructing the singleton.”
Fair enough, that brings to:
Plain-Old Globals Class
There’s really nothing wrong with have a class with a bunch of static fields that you get and set as needed. Just don’t hold onto any Contexts, or any objects that hold a reference to a context, like a View. Again, anything you set here will disappear when your Application is destroyed.
This is the way to go when you need information to persist across your app being destroyed and re-launched. SharedPreferences are a simple key-value store that you can access from anywhere that you have access to a Context. There’s a straightforward intro on the Android Developers site. Just make sure you don’t store things here that you DON’T want to persist indefinitely.
Avoid Global Application State
You should always cringe a little when you consider adding a “global” anything. It has its place, but it breaks encapsulation and adds complexity to your code – there’s always one more bit of information the code your working with COULD be dealing with, so there’s one more thing you need to keep in your head. Per the famous Mr. McConnell, we should always endeavor to structure our code such that working on any given chunk of it requires keeping track of as few things as possible.
The alternative to application state is often passing extras within the Intents that launch activities. If you’re writing a newspaper reader, you probably don’t need to store the current newspaper in a globally-accessible field. Rather, when the user clicks a newpaper to see it’s latest headlines, you pass in the newspaper ID as an Intent extra. When the user clicks a headline to see the article, you again pass along the newspaper in an Intent. The downside is that you have to add and read that bit of data to all Intents that care. The upside is that you have a better idea of what parts of your code are using what data. I generally prefer passing data around this way when I can.