I want to store the application context in a static member, like this, so I can access it, the shared preferences, resources etc. everywhere.
My question is whether the context can change itself during the application lifetime, so the stored context won't work in a proper way and I can't access shared preferences etc.
Or is the context immutable, so I can use it without any doubt?
Thanks for you answers!
Application context stays unaltered during application lifetime.
Context is immutable during all work of app. And you can use it in static way to get resources, shared preferences, etc.
When you look at the accepted answer of this post, you will find that it is Ok to do this, but handle with care...
There are a couple of potential problems with this approach,
though in a lot of circumstances (such as your example) it will work well.
In particular you should be careful when dealing with anything that deals with the GUI
that requires a Context. For example, if you pass the application Context into the
LayoutInflator you will get an Exception. Generally speaking, your approach is excellent:
it's good practice to use an Activity's Context within that Activity, and the Application
Context when passing a context beyond the scope of an Activity to avoid memory leaks.
Yep, you can use it with shared preferences and get resources etc.
getApplicationContext() function should do it. It shouldn't matter if its mutable.
Related
I am considering using the android Application class as a place to store temporary state and common code shared by other (fragment) activities in the app.
I would like to get more feedback as to whether it is a good place for:
Shared constants like ID's, pref key names, etc.
Global variables (i.e. setters/getters) reflecting current UI state, navigation, selected fragment, and, in general, temporary data that does not need to be persisted.
Hooks for persisting data when certain conditions are triggered.
Updating the UI after preference changes.
Providing an easy way to access the context from anywhere in the app, including code where getApplication() is not available, e.g. via a static getter such as MyApp.getApp().
Common methods that need the visibility of the global state variables and which would become too cumbersome to move away to dedicated classes.
What else would be appropriate/useful/handy to have in the activity class? What would not be a good idea to keep in it and what would be the best alternatives? And finally, what you have found Application to be best used for in your apps?
Shared constants like ID's, pref key names, etc.
I generally create a constants file called C for this, as its better for readability. C.SHARED_PREFS is easier to understand that Application.SHARED_PREFS IMHO.
Global variables (i.e. setters/getters) reflecting current UI state,
navigation, selected fragment, and, in general, temporary data that
does not need to be persisted.
This would be better off in the Activity or component which it concerns (for example, the UI state of an Activity should probably stored in the icicle bundle, or within that instance of the Activity).
Hooks for persisting data when certain conditions are triggered.
This should be fine.
Updating the UI after preference changes.
Again, I feel this would be better off in the respective component.
Providing an easy way to access the context from anywhere in the app,
including code where getApplication() is not available, e.g. via a
static getter such as MyApp.getApp().
This would work, but be careful of memory leaks. You should generally pass the context in as a parameter when calling the method from an Activity or Service or whatever. Less chances of a memory leak.
Common methods that need the visibility of the global state variables
and which would become too cumbersome to move away to dedicated
classes.
I feel it would be better to make the effort of dedicated classes, as when your app grows in features and size, this will become difficult to maintain.
It is probably some place where certain hooks can be attached.
For instance, if you use ACRA crash reporting library, you just need to use the Application class, because this is where ACRA is attached. This is that forced me to start using this class; I never needed the one before.
I've been rereading this and can't make a sense of it, could you, probably explain it to me?
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
Context which internally uses Context.getApplicationContext() when
first constructing the singleton.
From http://developer.android.com/reference/android/app/Application.html
I fail to see why there's no need to subclass Application. I often subclass it so I can access application context from everywhere. So, what shall be the proper way according to this document?
I think the idea is to avoid overloading the Application class but instead having multiple small singleton classes focused on different concerns.
That's probably what they mean by "more modular way".
Normally people make the "Application" class so that they can store objects in it to persist the entire lifetime of the app or transfer between activities. I think what that line is saying that simply making it static would achieve the same purpose, in a more "modular" way.
As for application context, did you already know about getApplicationContext()?
Just ironed out a bug in my Android app. I was trying to use getAssets() to pull a file from my assets directory. I subclassed Application and returned a "getApplicationContext" object so that all my classes can use a context whenever they need to.
But after much headache and NullPointerExceptions, it turns out that I needed to pass a local context variable and use THAT instead. If I use a global application context, getAssets doesn't work!
So why is this? What's so special about a local context variable that makes it work. I thought any old "Context" variable was enough to access the necessary methods and make them work properly!
A local context variable is also an Activity. The Activity provides extra functionality that the AssetManager, you call using getAssets(), uses. Android strictly uses contexts and not activities in order to avoid memory leaks. You should almost always use your Activity's context.
I've got a quick question on the best way to handle Android contexts. A lot of things (e.g. Service) require that you pass a context as a parameter. At the present time, I have a public static variable that is set to point to getApplication() and I just refer to this throughout my application where a context is required.
Is this ok to do? Or is there a better method to handle this? A lot of my classes don't extend Activity or service and as such, don't have access to this.getApplication().
Everything seems to work ok when I just pass in my static variable.
Is this ok to do?
The Application object, in some cases, will fail to work. For example, it sucks for UI-related stuff.
Dianne Hackborn, a leading Android engineer, has stated her regret at Application existing in the first place.
My general advice is to use Application only when you know specifically why it is superior to using your Activity, Service, etc. There are cases when it is the better answer (e.g., binding to services).
A lot of my classes don't extend Activity or service and as such, dont have access to this.getApplication().
Pass a suitable Context as a parameter, as the Android SDK does.
At the present time, I have a public static variable that is set to
point to getApplication() and I just refer to this throughout my
application where a context is required.
Is this ok to do?
No.
A context applies to the context in which it was obtained. That is, an activity has context for that activity, a service has context for the service, and so on. Now, a lot of folks do what you are doing, and as you observe, it seems to work. That doesn't mean it will continue to work or that it's good design. If that was the proper pattern, Android would have been designed with Context.INSTANCE that is available statically.
An activity, service, and application are contexts (isA). Receivers are passed a context to their onHandlerIntent() method. For all other classes you write, just get used to constructing them with a context. Out of habit, whenever I create a new class, I automatically add a constructor that accepts a context and add a private field to hold it.
When you need a context in a static method, you should pass it in directly as a parameter.
I have a question regarding the term 'context' in Android. I see that the context provides information about the environment the application runs in, however what is the difference between Application Context and Activity Context?
AND why do I do things like this:
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
Why do I pass the context into the constructor? Can anyone provide please help me understand what a context is, and what the context object is?
I do not want copy/paste from android Reference since I already have read it.....too many times without understanding.
They are both instances of Context, but the application instance is tied to the lifecycle of the application, while the Activity instance is tied to the lifecycle of an Activity. Thus, they have access to different information about the application environment.
If you read the docs at getApplicationContext it notes that you should only use this if you need a context whose lifecycle is separate from the current context. This doesn't apply in either of your examples.
The Activity context presumably has some information about the current activity that is necessary to complete those calls. If you show the exact error message, might be able to point to what exactly it needs.
But in general, use the activity context unless you have a good reason not to.
In simple word ill try to explain. Lets take your example
If you are using AlertDialog Builder how will that AlertDialog will understand where he will get displayed??? (If you are not in that activity)
Here context comes in picture. We pass Activity Context to the AlertDialog.In short AlertDialog will will appear in provided context.
This is what my understanding is correct me if I am wrong.
Class Overview
Interface to global information about an application environment. This
is an abstract class whose implementation is provided by the Android
system. It allows access to application-specific resources and
classes, as well as up-calls for application-level operations such as
launching activities, broadcasting and receiving intents, etc.
anddev website said it very clearly .
you must pass it to some other class so they can access global
information among other things.