getApplication() vs. getApplicationContext()

AndroidAndroid ActivityAndroid ServiceAndroid Context

Android Problem Overview


I couldn't find a satisfying answer to this, so here we go: what's the deal with Activity/Service.getApplication() and Context.getApplicationContext()?

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 Activity and Service, but not on Context? Shouldn't there always be a valid application instance available from anywhere?

Android Solutions


Solution 1 - Android

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, getApplication() and 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).

Why does 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 baseContext.getApplicationContext().

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 > Context which internally uses Context.getApplicationContext() when > first constructing the singleton.

I know this is not an exact and precise answer, but still, does that answer your question?

Solution 2 - Android

It seems to have to do with context wrapping. Most classes derived from http://developer.android.com/reference/android/content/Context.htm">`Context`</a> are actually a http://developer.android.com/reference/android/content/ContextWrapper.htm">`ContextWrapper`</a>;, which essentially delegates to another context, possibly with changes by the wrapper.

The context is a general abstraction that supports mocking and proxying. Since many contexts are bound to a limited-lifetime object such as an http://developer.android.com/reference/android/app/Activity.html">`Activity`</a>;, there needs to be a way to get a longer-lived context, for purposes such as registering for future notifications. That is achieved by http://developer.android.com/reference/android/content/Context.html#getApplicationContext%28%29">`Context.getApplicationContext()`</a>;. A logical implementation is to return the global http://developer.android.com/reference/android/app/Application.html">`Application`</a> 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 http://developer.android.com/reference/android/app/Application.html">`Application`</a> 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 http://developer.android.com/reference/android/app/Activity.html#getApplication%28%29">`Activity.getApplication()`</a> or http://developer.android.com/reference/android/app/Service.html#getApplication%28%29">`Service.getApplication()`</a> 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.

Solution 3 - Android

Compare getApplication() and getApplicationContext().

getApplication returns an Application object which will allow you to manage your global application state and respond to some device situations such as onLowMemory() and onConfigurationChanged().

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.

Solution 4 - Android

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMatthiasView Question on Stackoverflow
Solution 1 - AndroidPierre-Yves RicauView Answer on Stackoverflow
Solution 2 - Androidusethe4ceView Answer on Stackoverflow
Solution 3 - AndroidRivieraKidView Answer on Stackoverflow
Solution 4 - AndroidLenny PorterView Answer on Stackoverflow