欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

从源码深入理解Context以及相关创建过程

程序员文章站 2024-02-11 21:34:04
...

Context关联类

文章较长,分析了Application、Activity、Service各自Context启动过程,耐心看完,会让你思路更清晰

Context意为上下文,是一个应用程序环境信息的入口

使用场景:

  • 使用Context调用方法,比如启动Activity、访问资源、调用系统组件服务等等
  • 调用方法时传入Context,比如弹出Toast、创建Dialog等

Activity和Application都间接的继承自Context,因此一个app进程中有多少个Context,这个数量等于Activity的个数加上Service的个数再加上1,这个1就是Appliation内的Context

下面看下Context的关联类

从源码深入理解Context以及相关创建过程

ContextImpl和ContextWrapper继承自Context,ContextWrapper内包含有ContextImpl的引用mBase,mbase具体指向ContextImpl,Context属于装饰类,ContextWrapper是装饰类,它对ContextImp进行包装,ContextWrapper主要起到方法方法传递的作用,ContextWrapper中几乎所有使用到的方法都调用了ContextImpl中的相关方法实现的。

Service、Application都集成自ContextWrapper,因为Activity需要有个主题相关的方法,所以需要继承自ContextThemeWrapper方法

Application Context的创建过程

一个app启动完成之后就会有一个全局的Application Context,下面看下Application Context的创建过程流程图

从源码深入理解Context以及相关创建过程

ActivityThread类作为应用程序进程的主线程管理类,会调用ApplicationThread的scheduleLaunchActivity方法来启动Activity

ApplicationThread是ActivityThread的内部类,scheduleLaunchActivity方法在ActivityThread类内

ApplicationThread代码比较多,我们只摘出我们重点关心的

private class ApplicationThread extends IApplicationThread.Stub {
        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";

        private int mLastProcessState = -1;

        public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            int seq = getLifecycleSeq();
            if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
                    + " operation received seq: " + seq);
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
                    configChanges,
                    seq);
        }

        public final void scheduleStopActivity(IBinder token, boolean showWindow,
                int configChanges) {
            int seq = getLifecycleSeq();
            if (DEBUG_ORDER) Slog.d(TAG, "stopActivity " + ActivityThread.this
                    + " operation received seq: " + seq);
            sendMessage(
                showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
                token, 0, configChanges, seq);
        }

        public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
            sendMessage(
                showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
                token);
        }

        public final void scheduleSleeping(IBinder token, boolean sleeping) {
            sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
        }

        public final void scheduleResumeActivity(IBinder token, int processState,
                boolean isForward, Bundle resumeArgs) {
            int seq = getLifecycleSeq();
            if (DEBUG_ORDER) Slog.d(TAG, "resumeActivity " + ActivityThread.this
                    + " operation received seq: " + seq);
            updateProcessState(processState, false);
            sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0, 0, seq);
        }

        public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
            ResultData res = new ResultData();
            res.token = token;
            res.results = results;
            sendMessage(H.SEND_RESULT, res);
        }

        //scheduleLaunchActivity方法用来启动Activity
        @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中,通过发送Handler消息,在接受方接受
            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
省略....
}

可以看到ApplicationThread内部有很多管理Activity的方法:schedulePauseActivity、scheduleStopActivity等等,可见,操作Activity的声明周期的很多方法都经过ActivityThread类的ApplicationThread中的方法

ApplicationThread的scheduleLaunchActivity方法向H类中发送LAUNCH_ACTIVITY类型的消息,目的是将启动Activity的消息放到主线程的消息队列中,接下来查看H类中的handlerMessage方法对LAUNCH_ACTIVITY类型的处理

 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, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case RELAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                    handleRelaunchActivity(r);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case PAUSE_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, false,
                            (args.argi1 & USER_LEAVING) != 0, args.argi2,
                            (args.argi1 & DONT_REPORT) != 0, args.argi3);
                    maybeSnapshot();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case PAUSE_ACTIVITY_FINISHING: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
                            args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case STOP_ACTIVITY_SHOW: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
                    SomeArgs args = (SomeArgs) msg.obj;
                    handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case STOP_ACTIVITY_HIDE: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
                    SomeArgs args = (SomeArgs) msg.obj;
                    handleStopActivity((IBinder) args.arg1, false, args.argi2, args.argi3);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case SHOW_WINDOW:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
                    handleWindowVisibility((IBinder)msg.obj, true);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case HIDE_WINDOW:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
                    handleWindowVisibility((IBinder)msg.obj, false);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case SEND_RESULT:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
                    handleSendResult((ResultData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case EXIT_APPLICATION:
                    if (mInitialApplication != null) {
                        mInitialApplication.onTerminate();
                    }
                    Looper.myLooper().quit();
                    break;
                case NEW_INTENT:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
                    handleNewIntent((NewIntentData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case UNBIND_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
                    handleUnbindService((BindServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case SERVICE_ARGS:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
                    handleServiceArgs((ServiceArgsData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case STOP_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
                    handleStopService((IBinder)msg.obj);
                    maybeSnapshot();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case ACTIVITY_CONFIGURATION_CHANGED:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
                    handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj,
                            INVALID_DISPLAY);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case ACTIVITY_MOVED_TO_DISPLAY:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityMovedToDisplay");
                    handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj,
                            msg.arg1 /* displayId */);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case UNSTABLE_PROVIDER_DIED:
                    handleUnstableProviderDied((IBinder)msg.obj, false);
                    break;
                case REQUEST_ASSIST_CONTEXT_EXTRAS:
                    handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
                    break;
            }
            Object obj = msg.obj;
            if (obj instanceof SomeArgs) {
                ((SomeArgs) obj).recycle();
            }
            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
        }
}

以上是Handler内的消息处理方法,可以看到很多熟悉的方法:PAUSE_ACTIVITY、PAUSE_ACTIVITY_FINISHING、STOP_ACTIVITY_SHOW、SHOW_WINDOW、HIDE_WINDOW,可以推测,在Activity与AMS通信过程中的消息处理很多都是经过H类的handleMessage方法,我们继续看上面的LAUNCH_ACTIVITY选项

 final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

  r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
  handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");

ActivityClientRecord就是经过封装传递过来的参数,包括token、intent、info等,

继续看handleLaunchActivity的方法

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    //省略....
      Activity a = performLaunchActivity(r, customIntent);
    //省略....
    }

在handleLaunchActivity中又调用了ActivityThread的performLaunchActivity方法

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//省略。。。
try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
 } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

return activity;
}

继续查看makeApplication方法,makeApplication在LoadedAPK中,

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
//如果mApplication不为null,则返回mApplication,这里假设是第一次启动程序
        if (mApplication != null) {
            return mApplication;
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

        Application app = null;

        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
//通过ContextImpl的createAppContext方法创建ContextImpl
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//创建Application,在Instrumentation的newApplication方法注入classLoader类型的对象
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        mActivityThread.mAllApplications.add(app);
//将Appliccation赋值给LoaderApk的成员变量mApplication,这个Application就是Application的
 //   类型的对象,就是用来代表Application Context的
        mApplication = app;

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!instrumentation.onException(app, e)) {
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
        }

        // Rewrite the R 'constants' for all library apks.
        SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
        final int N = packageIdentifiers.size();
        for (int i = 0; i < N; i++) {
            final int id = packageIdentifiers.keyAt(i);
            if (id == 0x01 || id == 0x7f) {
                continue;
            }

            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
        }

        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        return app;
    }

继续查看mActivityThread.mInstrumentation.createAppContext方法,查看Application是如何创建的

newApplication方法在Instrumentation.java中

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

newApplication方法有两个,最后会调用上面这个,通过反射来获取Application,并调用attch方法,把ContextImpl传递进去,最后返回该Application

下面是Application.java中的attch方法

final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }

通过ContextImpl中的getImpl方法,得到LoadedApk(用来描述已加载过的APK文件)

在attachBaseContext中,它在Application的父类ContextWrapper中实现

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

这个base一路传递过来的是ontextImpl,它是Context的实现类,将ContextImpl赋值给ContextWrapper的Context成员变量mBase,这样在ContextWrapper中就可以使用Context的方法,而Applicaton继承自ContextWrapper,同样可以使用Context的方法,Application的attch方法就是使Applicattion可以使用Context的方法,这样Application才可以用来代表Appliccation Context,

Appliccation Context创建过程讲解完成,下面来看看Activity Context的创建过程

 

Activity Context的创建过程

下面看下Activity的Context创建过程的流程图

从源码深入理解Context以及相关创建过程

可以看到Application的Context启动流程和Activity的Context启动流程图有很多相似的地方,都是在ApplicationThread中启动scheduleLaunchAcctivity,然后经过主线程ActivityThread,再发送消息Handler到具体的地方,从发送消息这里开始有不同之处,上面几个流程可以看Application 的Context启动过程,activity的Context启动流程就从Handler发送消息开始说起

H类中的handleMessage方法会对LAUNCH_ACTIVITY类型的消息进行处理,其中调用了ActivityThread的handleLaunchActivity方法,而在handlerLaunchActivity方法中又调用了ActivityThread的performlaunchActivity方法,我们直接来看performlaunchActivity方法

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
       //省略...
//创建ContextImpl
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
//创建了Activity的实例
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            //省略。。。
        }

        try {
            //省略....
            if (activity != null) {
               //省略...
                appContext.setOuterContext(activity);
                //参数appContext就是上面创建的,Activity绑定了attch方法,这个attch就    
 //是Activity的attch方法
                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);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
//以下方法中的callActivityOnCreate方法会调用Activity的onCreate生命周期方法
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }

查看以上代码中的activity方法中的attach方法,这个方法是启动Activity必须要走的方法,也是第一个方法,看看这个方法中都做了什么

attach方法在Activity类中

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) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);
        //实例化一个PhoneWindow
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
//通过setCallback把PhoneWindow触发的事件传递给Activity
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            mWindow.setSoftInputMode(info.softInputMode);
        }
        if (info.uiOptions != 0) {
            mWindow.setUiOptions(info.uiOptions);
        }
         //UI主线程
        mUiThread = Thread.currentThread();

        mMainThread = aThread;
        mInstrumentation = instr;
        mToken = token;
        mIdent = ident;
        mApplication = application;
        mIntent = intent;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
        if (voiceInteractor != null) {
            if (lastNonConfigurationInstances != null) {
                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
            } else {
                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                        Looper.myLooper());
            }
        }

        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;

        mWindow.setColorMode(info.colorMode);
    }

查看源码可以看到实例化了一个PhoneWindow,它代表应用程序窗口,PhoneWindow在运行间会简介触发很多事件,比如点击事件、触摸事件、屏幕焦点变化等事件,这些事件都会转化该与Activity相关联的Activity,转发操作通过Window.setCallback实现

以上代码中的有个attachBaseContext方法,这个方法是在ContextThemeWrapper实现的,ContextThemeWrapper实现的attchBaseContext又调用了父类ContextWrapper的attchBaseContext方法:

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

倒数第二行的mBase=base中的base就是一路传递过来的Activity的ContextImpl,将它赋值给ContextWrapper的成员变量mBase,这样ContextWrapper的功能就能交给ContextImpl来处理了

总结一下:在启动Activity的过程中创建ContextImpl,并赋值给ContextWrapper的成员变量mBase,Activity继承自ContextWrapper的子类ContextWrapperTheme,这样在Activity中就可以使用Context中定义的方法了。

这里插播个面试题:Activity、Window、WindowPhone之间的关系?看过上面Activity关联Context的流程,能否从容应对这个面试题

 

Service的Context创建过程

Service创建过程与Activity的Context过程类似,流程图可以参考Activity的Context的流程图,这里不再给出,大概流程:ActivityThread内部类AppliccationThread会调用scheduleCreateService方法来启动Service。

sendmessage方法向H类发送一个CREATE_SERVICE类型的消息,handleMessage方法会对CREATE_SERVICE类型的消息进行处理

private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
            //此处创建ContextImpl
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            //将上面创建好的context作为参数传入到attach中
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            service.onCreate();
            mServices.put(data.token, service);
            try {
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }

关键代码部分有注释,下面看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;
    }

继续查看上面代码的attachBaseContext(context)方法

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

可以看到,Service的Context创建过程和Activity的类似,base都是一路传递过来的ContextImpl,将ContextImpl赋值给ContextWrapper的Context类型的成员变量mBase,这样在ContextWrapper就可以使用Context的方法了,Servive继承自ContextWrapper,同样可以使用Context中的方法。

到此分析完成!

相关标签: android 底层