Context完全解析(三)Activity的Context创建过程

请求启动一个Activity时ActivityManagerService 会通过IPC调周到ActivityThread类的scheduleLaunchActivity()方法

public final class ActivityThread {
    ......
    private class ApplicationThread extends IApplicationThread.Stub {
        ......
        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            ......

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            ......
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
        ......
    }
    ......
}

    其中该方法有一个ActivityInfo类型的参数 , 这是一 个实现了Parcelable接口的数据类, 它是由AmS创建的, 并通过IPC传递到ActivityThread中的。然后使用这些传入的参数来构建一个ActivityClientRecord对象r , 这是个数据类,代表的就是一个本地Activity对象的记录,ActivityThread内部会为每 一 个Activity创建一 个ActivityClientRecord对象 , 并使用这些数据对象来管理Activity。scheduleLaunchActivity()方法接下来通过H类发送 一 个LAUNCH_ACTIVITY消息, H类 继承于Handler, 下面看看H类的定义。

public final class ActivityThread {
    ......     
    private class H extends Handler {
         public static final int LAUNCH_ACTIVITY         = 100;
         public static final int PAUSE_ACTIVITY          = 101;
         ......
         public void handleMessage(Message msg) {
           
            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, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                ......    
            }
            ......   
         }
         ......
     }
   ......
}
    从H类的定义可知, 它是 一 个继承Handler的ActivityThread内部类, 主要用 来在ActivityThread内部分发消息。当前面scheduleLaunchActivity()方法里发送了 LAUNCH ACTIVITY 消息之后, 最终系统会分发这个消息进入到H 类中的
handleMessage()方法, 在H类的handleMessage()方法则调用 ActivityThread类的handleLaunchActivity() 方法来继续处理。
public final class ActivityThread {
    ......
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ......

        Activity a = performLaunchActivity(r, customIntent);

        ......
    }
}
 handleLaunchActivity()方法首先调用了performLaunchActivity()方法, 这个方法 主要用于创建Application Context和Activity Context。 下面来看看performLaunchActivity()方法如何创建Activity  Context。
public final class ActivityThread {
    ......
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }
        ......
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ......
        } catch (Exception e) {
            ......
        }

        try {
            //下面创建Appication
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ......
            //下面是对Activity的处理
            if (activity != null) {
                ......   
                appContext.setOuterContext(activity);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
                ......
            }
            ......      
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            .......
        }

        return activity;
    }
   performLaunchActivity()方法首先会调用getPackageInfo方法来获取一个LoadedApk对象,这个对象在创建Application时已经保存在ActivityThread的变量中了,可以直接取得。接着调用createBaseContextForActivity方法来创建Activity的context实例,接着创建Activity实例,之后再调用LoadedApk对象的makeApplication方法来创建Application实例,由于进程启动的时候就已经创建了Application对象并保存在LoadedApk对象的mApplication变量中,这里会直接返回这个Application对象。但是,由于LoadedApk对象是弱引用保存的,可能会被回收而需要重新new出来,这将导致新的LoadedApk对象里面的mApplication对象实例为空,此时会在makeApplication方法中重新创建一个Application对象。下面来看看createBaseContextForActivity方法如何创建Activity的ContextImpl实例。
public final class ActivityThread {
    ......
    private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
        ......

        ContextImpl appContext = ContextImpl.createActivityContext(
                this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);

        ......
        return appContext;
    }
    ......
}
ActivityThread 的 createBaseContextForActivity ()方法通过调用 Contextlmpl 类的 createActivityContext()静态方法, 来创建 Contextlmpl 类实例对象 appContext , 而 createActivityContext ()方法的真正实现就是 new 了 一 个 Contextlmpl 实例。 
    这 一 步执行完成之后, 回到前面的ActivityThread类的performLaunchActivity()方法 中, 接下来就会调用 Instrumentation
对象的newActivity()方 法用于创建 一 个Activity实例。
public class Instrumentation {
    ......
    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }
    ......
}
   cl是 一 个类加载器, className是 一 个Activity 子类的名字, 在应用程序开发中, 都用 一 个子类来继承Activity,所以cl.loadClass(className) .new Instance()会通过反射来创建 一 个  Activity类的实例。子 Activity实例在创建 过程中会调用父类 Activity 的默认构造方 法。由于Activity没有定义自己的构造方法, 因此, 系统会为它提供 一 个默认的构造 方法, 但是, 系统为Activity类提供的默认构造方法什么也没做, 也就是说Activity 类实例在创建的时候, 还没有执行实质性的初始化工作, 这个初始化工作由Activity 的attach()方法完成。
     创建完Activity后返回到 performLaunchActivity方法中继续执行,因为activity!=null,所以会接着调用 appContext.setOuterContext(activity)方法,并且将activity实例作为参数传入,这样Contextlmpl实现类实例就会持有一个包装类
ContextWrap类实例,这里就是Activity,以后 Contextlmpl 也可以访问 Activity 中的变量和方法。接着调用Activity的attach方法,这个方法主要是对activity进行初始化,其内部会调用 attachBaseContext (context)方法,并且将 Contextlmpl类实例作为参数传入,保存在其父类ContextWrap的mBase实例变量中,这样Activity中就持有了Contextlmpl类实例,也就是Activity的Context创建完成。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值