Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is getApplicationContext() of Application class called?

I have an Application class in which i override getApplicationContext().

I've looked in the Android Source code and I'm unable to find from where it's called?

The inheritance hierarchy is:

Application -> ContextWrapper -> Context

public abstract Context getApplicationContext();

getApplicationContext() is an abstract method in Context class which is overridden in ContextWrapper class.

@Override
public Context getApplicationContext() {
    return mBase.getApplicationContext();
}

mBase is reference to an object of type Context which is initialized in ContextWrapper's constructor but as per the code Application's class constructor passes null to the constructor of super() i.e. constructor of ContextWrapper.

public Application() {
    super(null);
}

Now the only possible way to pass context is via :

protected void attachBaseContext(Context base) {
    if (mBase != null) {
        throw new IllegalStateException("Base context already set");
    }
    mBase = base;
}

but there is no call to this method either. Please help me in finding that from where is getApplicationContext() called then?

NOTE : Please don't post any links to such questions as I've gone through each one of them but still no concrete answer.

like image 300
CodeWarrior Avatar asked Jul 22 '14 09:07

CodeWarrior


People also ask

When would you call getApplicationContext () and why?

This method is generally used for the application level and can be used to refer to all the activities. For example, if we want to access a variable throughout the android app, one has to use it via getApplicationContext().

When would you call getApplicationContext () Select all that apply?

You only use getApplicationContext() when you know you need a Context for something that may live longer than any other likely Context you have at your disposal. Scenarios include: Use getApplicationContext() if you need something tied to a Context that itself will have global scope.

What is the use of getApplicationContext in Android?

getApplicationContext() : Returns the context for the entire application (the process all the Activities are running inside of). Use this instead of the current Activity context if you need a context tied to the lifecycle of the entire application, not just the current Activity.

How do I find application context?

To get a reference to the ApplicationContext in a Spring application, it can easily be achieved by implementing the ApplicationContextAware interface. Spring will automatically detect this interface and inject a reference to the ApplicationContext: view rawMyBeanImpl. java hosted by GitHub.


2 Answers

I guess the question is rather "where is attachBaseContext() called for the Application object?"

See Application.java:

/**
 * @hide
 */
/* package */ final void attach(Context context) {
    attachBaseContext(context);
    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

If you go a little further up the call chain, you will find Instrumentation.newApplication() (Instrumentation.java) and finally LoadedApk.makeApplication() (LoadedApk.java), which are called as the application is being started:

    java.lang.ClassLoader cl = getClassLoader();
    ContextImpl appContext = new ContextImpl();
    appContext.init(this, null, mActivityThread);
    app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
    ...
    mApplication = app;

In short, the base Context supplied to the Application class is a ContextImpl instance, created right in this method.

And, if you check ContextImpl.getApplicationContext():

@Override
public Context getApplicationContext() {
    return (mPackageInfo != null) ? mPackageInfo.getApplication() : mMainThread.getApplication();
}

you'll see that it actually ends up calling LoadedApk.getApplication() (since mPackageInfo is the LoadedApk instance), which is the mApplication field set by the makeApplication() method mentioned before.

In short, after all this is set up, Application.getApplicationContext() ends up returning... the very same Application instance. :)

like image 79
matiash Avatar answered Oct 07 '22 12:10

matiash


Context is set through setBaseContext method, when an Activity / Service / Receiver instance is created for the first time. Here is the call stack:

ContextWrapper::attachBaseContext <-- Application::attach <-- Instrumentation::newApplication <-- LoadedApk::makeApplication <-- ActivityThread::performLaunchActivity || ActivityThread::handleReceiver || ActivityThread::handleCreateService || ActivityThread::handleBindApplication

like image 6
Manish Mulimani Avatar answered Oct 07 '22 13:10

Manish Mulimani