Context(二)--Application创建Context

151 阅读2分钟

「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战

Android应用程序的入口函数是ActivityThread类的main()函数,经过一系列调用,最终到了performLaunchActivity()方法里

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  ...
  Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ...
        return activity;
    }

我们看看makeApplication()内部

  • (1)它会先判断是否已经有了mApplication,如果有了就直接返回
  • (2)调用ContextImpl.createAppContext,创建appContext
  • (3)创建app实例
  • (4)将(3)创建的app赋值给appContext
@UnsupportedAppUsage
    public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {
    // (1)
    if (mApplication != null) {
        return mApplication;
    }
    ...
    try{
        // (2)
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        //(3)
        app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
        //(4)
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ...
        }
        ...
        return app;
    }

我们看一下newApplication()是如何创建Application的

public Application newApplication(ClassLoader cl, String className, Context context)throws InstantiationException, IllegalAccessException,ClassNotFoundException {
        app.attach(context);
        return app;
}

我们再看看attach()方法都做了哪些操作

  • 在attachBaseContext()方法中,Application继承ContextWapper,所以会调用ContextWapper的attachBaseContext,将base赋值给ContextWrapper中的mBase
  • context是在makeApplication方法中通过ContextImpl.createAppContext创建的,所以是一个ContextImpl类型的Context,到这里Application的Context创建就结束了
final void attach(Context context) { 
  attachBaseContext(context);
}

最后总结一下:

  • 在application创建的时候,首先会检查Application是否已经创建

    一个应用程序进程中只能创建一个 Application对象,如果之前已经创建过Application对象,就不会再创建Application对象,Application对象在整个进程中是一个单例

  • 创建Appication及其Context

    如果之前没有创建过Application,调用ContextImpl.createAppContext()创建Application的ContextImpl实例,之后会调用newApplication方法,传入 ContextImpl实例。在newApplication方法内部,创建完Application实例后,会调用其attach方法并传入ContextImpl实例,在attach方法中会调用其父类ContextWrapper.attachBaseContext()方法,将ContextImpl对象设置给内部实例变量mBase,这样Application内部就持有了Context的实现类ContextImpl实例

  • 保存创建的Appication

    创建完一个Application对象后,将其保存在mApplication实例变量中

  • Application的onCreate()方法

    当创建完一个Application对象后,就会回调其onCreate方法,在该方法中可以做一些全局的初始化工作