I couldn’t find a satisfying answer to this, so here we go: what’s the deal with
In our application, both return the same object. In an
ActivityTestCase however, mocking the application will make
getApplication() come back with the mock, but
getApplicationContext will still return a different context instance (one injected by Android). Is that a bug? Is it on purpose?
I don’t even understand the difference in the first place. Are there cases outside a test suite where both calls may come back with different objects? When and why? Moreover, why is
getApplication defined on
Service, but not on
Context? Shouldn’t there always be a valid application instance available from anywhere?
Very interesting question. I think it’s mainly a semantic meaning, and may also be due to historical reasons.
Although in current Android Activity and Service implementations,
getApplicationContext() return the same object, there is no guarantee that this will always be the case (for example, in a specific vendor implementation).
So if you want the Application class you registered in the Manifest, you should never call
getApplicationContext() and cast it to your application, because it may not be the application instance (which you obviously experienced with the test framework).
getApplicationContext() exist in the first place ?
getApplication() is only available in the Activity class and the Service class, whereas
getApplicationContext() is declared in the Context class.
That actually means one thing : when writing code in a broadcast receiver, which is not a context but is given a context in its onReceive method, you can only call
getApplicationContext(). Which also means that you are not guaranteed to have access to your application in a BroadcastReceiver.
When looking at the Android code, you see that when attached, an activity receives a base context and an application, and those are different parameters.
getApplicationContext() delegates it’s call to
One more thing : the documentation says that it most cases, you shouldn’t need to subclass Application:
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
first constructing the singleton.
I know this is not an exact and precise answer, but still, does that answer your question?
getApplicationContext returns the global application context – the difference from other contexts is that for example, an activity context may be destroyed (or otherwise made unavailable) by Android when your activity ends. The Application context remains available all the while your Application object exists (which is not tied to a specific
Activity) so you can use this for things like Notifications that require a context that will be available for longer periods and independent of transient UI objects.
I guess it depends on what your code is doing whether these may or may not be the same – though in normal use, I’d expect them to be different.
The context is a general abstraction that supports mocking and proxying. Since many contexts are bound to a limited-lifetime object such as an
Activity, there needs to be a way to get a longer-lived context, for purposes such as registering for future notifications. That is achieved by
Context.getApplicationContext(). A logical implementation is to return the global
Application object, but nothing prevents a context implementation from returning a wrapper or proxy with a suitable lifetime instead.
Activities and services are more specifically associated with an
Application object. The usefulness of this, I believe, is that you can create and register in the manifest a custom class derived from
Application and be certain that
Service.getApplication() will return that specific object of that specific type, which you can cast to your derived
Application class and use for whatever custom purpose.
In other words,
getApplication() is guaranteed to return an
Application object, while
getApplicationContext() is free to return a proxy instead.
To answer the question, getApplication() returns an Application object and getApplicationContext() returns a Context object. Based on your own observations, I would assume that the Context of both are identical (i.e. behind the scenes the Application class calls the latter function to populate the Context portion of the base class or some equivalent action takes place). It shouldn’t really matter which function you call if you just need a Context.