简体   繁体   English

什么时候调用Application类的getApplicationContext()?

[英]When is getApplicationContext() of Application class called?

I have an Application class in which i override getApplicationContext() . 我有一个Application类,其中我重写了getApplicationContext()

I've looked in the Android Source code and I'm unable to find from where it's called? 我查看了Android源代码,我无法找到它所在的位置?

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. getApplicationContext()Context类中的一个抽象方法,它在ContextWrapper类中被重写。

@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() ie constructor of ContextWrapper . mBase引用Context类型的对象,它在ContextWrapper的构造函数中初始化,但是根据代码,Application的类构造函数将null传递给super()构造函数,即ContextWrapper构造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? 请帮助我找到getApplicationContext()所在的地方?

NOTE : Please don't post any links to such questions as I've gone through each one of them but still no concrete answer. 注意:请不要发布任何链接到这些问题,因为我已经完成了每个问题,但仍然没有具体的答案。

I guess the question is rather "where is attachBaseContext() called for the Application object?" 我想问题是“在哪里调用Application对象的attachBaseContext() ?”

See Application.java : 请参阅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: 如果你在调用链上走得更远,你会发现Instrumentation.newApplication()Instrumentation.java ),最后是LoadedApk.makeApplication()LoadedApk.java ),它们在应用程序启动时被调用:

    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. 简而言之,提供给Application类的基本Context是一个ContextImpl实例,在此方法中创建。

And, if you check ContextImpl.getApplicationContext() : 并且,如果您检查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. 你会发现它实际上最终调用了LoadedApk.getApplication() (因为mPackageInfoLoadedApk实例),这是前面提到的makeApplication()方法设置的mApplication字段。

In short, after all this is set up, Application.getApplicationContext() ends up returning... the very same Application instance. 简而言之,在设置完所有这些之后, Application.getApplicationContext()最终返回...完全相同的Application实例。 :) :)

 public class ContactManagerApplication extends Application {
public static Context context = null;

 @Override
public void onCreate() {
    super.onCreate();
    Log.d("@gaurav", getApplicationContext()+"");
    context = getApplicationContext();

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM