美文网首页
Activity和Service的Context的创建过程

Activity和Service的Context的创建过程

作者: code希必地 | 来源:发表于2020-09-11 16:57 被阅读0次

1、Activity的Context创建过程

Context是在Activity的启动过程中创建的,这里就从Activity的启动开始分析。Activity的启动会调用ActivityThread的内部类ApplicationThreadscheduleLaunchActivity(),我们就从这个方法开始。
ApplicationThread##scheduleLaunchActivity()

@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) {
        updateProcessState(procState, false);
        ActivityClientRecord r = new ActivityClientRecord();
        r.token = token;
        ...
        sendMessage(H.LAUNCH_ACTIVITY, r);
}

scheduleLaunchActivity方法会将启动Activity的参数封装成ActivityClientRecordsendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord 传递过去。sendMessage方法的目的是将启动Activity的逻辑放在主线程中的消息队列中,这样启动Activity的逻辑就会在主线程中执行。
H类的handleMessage方法中会对LAUNCH_ACTIVITY类型的消息进行处理,其中调用了handleLaunchActivity方法
ActivityThread##handleLaunchActivity()

 @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        //...
        final Activity a = performLaunchActivity(r, customIntent);
        //...

        return a;
    }

里面调用了performLaunchActivity(),继续往下跟
ActivityThread##performLaunchActivity()

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);
        }

        //创建Activity的Context
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //创建Activity,内部通过反射创建的
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            //....
        } catch (Exception e) {
            //....
        }

        try {
            //.....

            if (activity != null) {
                //将Activity赋值给ContextImpl中的mOuterContext
                appContext.setOuterContext(activity);
                //调用Activity的attach()方法
                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);

                //调用Activity的onCreate()
                 if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
            }
           //....

        } 
        //....

        return activity;
    }

方法中逻辑比较负责,这里只保留了Activity的Context创建的相关代码,代码中已经做了注释,这里主要看下activity.attach()
Activity##attach()

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
        //调用其父类ContextWrapper,将创建的ContextImpl传递给mBase
        attachBaseContext(context);

        //创建Window
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        //设置回调,PhoneWindow中的点击事件、按键事件、滑动事件通过callBack传递给Activity
        mWindow.setCallback(this);
        //...
        //给Window设置WindowManager
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        //将WindowManager赋值给Activity的成员变量,所以在Activity中可以直接调用getWindowManager()来获取WindowManager
        mWindowManager = mWindow.getWindowManager();
        //....
    }

这里主要看下attachBaseContext(context),它的实现在ContextWrapper
ContextWrapper##attachBaseContext(context)

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

和Application Context一样,Activity Context创建完成后会一直传递给ContextImplmBase。这样ContextWrapper的处理就可以交由Contextimpl来处理了。至此Activity的Context创建流程就结束了,下面总结一下:

Activity Context的创建

2、Service Context创建流程

和Activity Context创建流程类似,Service的创建是在ActivityThread的内部类ApplicationThreadscheduleCreateService()
ApplicationThread##scheduleCreateService()

public final void scheduleCreateService(IBinder token,
         ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
     ...
     sendMessage(H.CREATE_SERVICE, s);
 }

ApplicationThread中向H发送H.CREATE_SERVICE类型的消息,在handleMessage()中会调用ActivityThread.handleCreateService()
ActivityThread##handleCreateService()

 private void handleCreateService(CreateServiceData data) {
        //....
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            //创建Service 内部使用反射创建
            service = packageInfo.getAppFactory()
                    .instantiateService(cl, data.info.name, data.intent);
        } catch (Exception e) {
            //.....
        }

        try {

            //创建ContextImpl
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
    
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            //调用Service的attach()
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            //调用Service的onCreate()
            service.onCreate();
            mServices.put(data.token, service);
            //....
        } catch (Exception e) {
           //.....
        }
    }

该方法中创建了ServiceContextImpl并调用了Service.attach()
Service##attach()

  public final void attach(
            Context context,
            ActivityThread thread, String className, IBinder token,
            Application application, Object activityManager) {
        attachBaseContext(context);
        mThread = thread;           // NOTE:  unused - remove?
        mClassName = className;
        mToken = token;
        mApplication = application;
        mActivityManager = (IActivityManager)activityManager;
        mStartCompatibility = getApplicationInfo().targetSdkVersion
                < Build.VERSION_CODES.ECLAIR;
    }

attach()中调用attachBaseContext(context)attachBaseContext(context)的具体实现是在ContextWrapper
ContextWrapper##attachBaseContext()

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

可以看到最终将创建的ContextImpl传递给ContextWrapper的mBase。

相关文章

网友评论

      本文标题:Activity和Service的Context的创建过程

      本文链接:https://www.haomeiwen.com/subject/ircbektx.html