I’m reading this article on how to : correctly retain variable state in Android and I’m reminded that I’ve never gotten a good answer (and can’t find one here) for why it’s better to tussle with the Bundle (which isn’t a HUGE hassle, but definitely has its limitations) rather than just always have an Application overridden in your App, and just store all your persistent data members there. Is there some leakage risk? Is there a way that the memory can be released unexpectedly? I’m just not clear on this… it SEEMS like it’s a totally reliable “attic” to all the Activities, and is the perfect place to store anything that you’re worried might be reset when the user turns the device or suspends the app.
Am I wrong on this? Would love to get some clarity on what the true life cycle of the memory is in the Application.
Based on the answers below, let me extend my question.
Suppose I have an app that behaves differently based on an XML file that it loads at startup.
Specifically, the app is a user-info gathering app, and depending on the XML settings it will follow an open ended variety of paths (collecting info A, but not J, and offering Survey P, followed by an optional PhotoTaking opportunity etc.)
Ideally I don’t have to store the details of this behavior path in a Bundle (god forbid) or a database (also ugly, but less so). I would load the XML, process it, and have the Application hold onto that structure, so I can refer to it for what to do next and how. If the app is paused and the Application is released, it’s not *THAT big a hassle to check for null in my CustomFlow object (that is generated as per the XML) and re-instantiate it. It doesn’t sound like this would happen all that often, anyway. Would this be a good example of where Application is the *best tool?
The question as to which method is better largely depends upon what information you are storing and need access to and who (which components, packages, etc.) needs access to that information. Additionally, settings like
launchModeandconfigChangeswhich alter the lifecycle can help you to determine which method is best for you.First, let me note, that I am a huge advocate for extending the Application object and often extend the Application class, but take everything stated here in its context as it is important to understand that there are circumstances where it simply is not beneficial.
On the Lifecycle of an Application: Chubbard mostly correctly stated that the Application has the same life as a Singleton component. While they are very close, there are some minute differences. The Application itself is TREATED as a Singleton by the OS and is alive for as long as ANY component is alive, including an AppWidget (which may exist in another app) or ContentResolver.
All of your components ultimately access the same object even if they are in multiple Tasks or Processes. However, this is not guaranteed to remain this way forever (as the Application is not ACTUALLY a Singleton), and is only guaranteed in the Google Android, rather than the manufacturer overridden releases. This means that certain things should be handled with care within the Application Object.
Your
Applicationobject will not die unless all of your components are killed as well. However, Android has the option to kill any number of components. What this means is that you are never guaranteed to have anApplicationobject, but if any of your components are alive, there IS anApplicationto associate it to.Another nice thing about
Applicationis that it is not extricably bound to the components that are running. Your components are bound to it, though, making it extremely useful.Things to Avoid in Application Object:
Contexts. In fact, often, you shouldn’t store aContextin here at all, because theApplicationis aContextitself.Applicationobject, even though its extremely likely.Application, the type of you data and methods store here will help you further determine whether you need to make a Singleton component or not.Drawablesand its derivatives are the most likely to “leak” if not taken care of, so it is also recommended that you avoid references toDrawableshere as well.Applicationobject. Additionally, none of the lifecycle events that occur in anActivityare available here.Things to store in the Application (over Bundle)
The
Applicationis an awesome place to store data and methods that must be shared between components, especially if you have multiple entry points (multiple components that can be started and run aside from a launch activity). In all of myApplications, for instance, I place my DEBUG tags and Log code.If you have a ContentProvider or BroadcastReceiver, this makes
Applicationeven more ideal because these have small lifecycles that are not “renewable” like theActivityorAppWidgetProviderand can now access those data or methods.Preferences are used to determine, typically, run options over multiple runs, so this can be a great place to handle your
SharedPreferences, for instance, with one access rather than one per component. In fact, anything that “persists” across multiple runs is great to access here.Finally, one major overlooked advantage is that you can store and organize your Constants here without having to load another class or object, because your
Applicationis always running if one of your components is. This is especially useful for Intent Actions and Exception Messages and other similar types of constants.Things to store in Bundle rather than Application
Run-time state that is dependent upon the presence or state of a single component or single component run. Additionally, anything that is dependant upon the display state, orientation, or similar Android Services is not preferrable here. This is because
Applicationis never notified of these changes. Finally, anything that depends upon notification from that Android System should not be placed here, such as reaction to Lifecycle events.And…. Elsewhere
In regard to other data that needs to be persisted, you always have databases, network servers, and the File System. Use them as you always would have.
As useful and overlooked as the
Applicationis, a good understanding is important as it is not ideal. Hopefully, these clarifications will give you a little understanding as to why gurus encourage one way over the other. Understand that many developers have similar needs and most instruction is based on what techniques and knowledge a majority of the community has. Nothing that Google says applies to all programmer’s needs and there is a reason that the Application was not declaredFinal.Remember, there is a reason Android needs to be able to kill your components. And the primary reason is memory, not processing. By utilizing the Application as described above and developing the appropriate methods to persist the appropriate information, you can build stronger apps that are considerate to the System, the User, its sibling components AND other developers. Utilizing the information that everyone here has provided should give you some great guidance as to how and when to extend your
Application.Hope this helps,
FuzzicalLogic