Application 运行上下文环境 Context的创建过程

Application 运行上下文环境 Context的创建过程

在android应用程序中,可以使用getApplicationContext()方法来获得应用程序的全局Context,在引用程序的任何位置都可以通过getApplicationContext()方法得到该Context对象,那么这个方法获得的Context在框架中是怎么创建的呢?
图为Application Context 类关系图

Created with Raphaël 2.1.2ApplicationApplicationContextWrapperContextWrapperContextContextContextImplContextImplmBasemOuterContext

从图中可知,Application继承ContextWrapper,ContextWrapper继承Context,ContextImpl也继承Context,ContextImpl是Context的真正实现,mOuterContext对象是Application的实例,它通过ContextImpl类的静态方法setOuterContext()设置值,而mBase对象是一个ContextImpl实例,它通过Application的attach() 方法来被赋值
接下来看一下Application Context是怎么创建的
当启动一个Activity的时候,android系统Framwork框架里的ActivityManagerService核心方法会调入应用程序客户端ActivityThread类的ScheduleLauncherActivity()方法里,下面分析Application Context创建过程,如下图:

Created with Raphaël 2.1.2ActivityThreadActivityThreadLoadedApkLoadedApkContextImplContextImplInstrumentationInstrumentationApplicationApplicationscheduleLaunchActivity()performLaunchActivity()makeApplication()createAppContext()newApplication()attach()attachBaseContext()setOuterContext(app)

scheduleLaunchActivity()防范会通过H类发送一个LAUNCH_ACTIVITY消息,H类继承handler,接下来看H类的定义

private class H extends Handler {
    ...
     public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
}

H 类是一个继承handler的ActivityThread的内部类,主要用在ActivityThread内部分发消息,前面发送了LAUNCH_ACTIVITY消息之后,最终系统会分发这个消息进入到H类中的handleMessage()方法中,调用handleLaunchActivity方法继续处理

  private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
       ...
        WindowManagerGlobal.initialize();

        Activity a = performLaunchActivity(r, customIntent);
        ...

performLaunchActivity()主要用于创建Application Context和Activity Context,接下来看一下这个方法

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

这个方法里面packageInfo是LoadedApk类型的对象,接着调用makeApplication方法继续处理

  public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        ...
        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                initializeJavaContextClassLoader();
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;
        ....
 }

createAppContext()方法创建了一个ContextImpl的实例,然后又通过newApplication()创建了一个Application的对象app,在newApplication方法中,会把appContext对象作为参数传递到Application中,赋值给ContextWrapper类里的mBase对象,当app对象创建好之后,就调用setOuterContext方法,把app赋值给ContextImpl的mOuterContext变量,最后把app赋值给LoadedApk的全局变量mApplication,mInstrumentation是Instrumentation类型的对象,接下来看一下newApplication方法的实现

  static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

这个方法首先创建了一个Application类型的对象app,然后调用attach方法把ContextImpl对象context赋值给ContextWrapper类的mBase对象,

 final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }
  protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }

到此Application Context的创建过程就介绍完了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值