Context简介
从谷歌对Context的介绍可知:
- Context是一个应用程序环境信息的接口,表示上下文的意思
- Context是一个抽象类,Android系统提供了该抽象类的具体实现类,即ContextImpl类,这里用到了一种代理模式
- 通过Context类获取应用程序的资源和类,也可以进行应用程序的操作,如启动Activity、发送广播、接受Intent信息等
应用程序中Context的总数目为:
总Context个数 = Activity个数 + Service个数 + 1(Application Context)
由于Service类和Activity类都是继承Context的,应用程序被启动后,还会为应用程序创建一个全局的Application对应的Context对象。Context是基类,Activity、Service、Application都是间接继承它。ContextImpl类继承了COntext,它才是Context的真正实现。ContextWrapper类中的变量mBase是一个ContextImpl对象,指向真正的实现类ContextImpl,而ContextImpl类中的mOuterContext是一个Context对象,指向相对应的Activity或Service或Application。
Context关系图如下所示:
Application Context创建过程
创建Application Context
当一个应用程序被启动之后,应用程序里就有一个Application Context对象,这个Context对象通过LoadedApk.java的makeApplication()方法创建。
当应用程序进程启动之后,Android系统Framework框架里的ActivityManagerService核心服务会调入应用程序客户端ActivityThread类的scheduleLaunchActivity()方法里。从该方法开始分析Context的创建过程,先看看ActivityThread类的scheduleLaunchActivity()方法。
schduleLaunchActivity()方法通过ActivityManagerService服务调用。首先,这个对象会生成一个内部类ActivityClientRecord对象r,并且把它里面的变量token赋值。这个token变量是AMS中ActivityRecord类里面的一个binder对象,这个token对象会同时传到应用程序ActivityThread和WindowManagerService(WMS),关于token此处不继续展开。scheduleLaunchActivity()方法会通过H类发送一个LAUNCH_ACTIVITY消息,H类继承于Handler,是ActivityThread的内部类,主要用于在ActivityThread内部分发消息。看看H类的定义:
在H类的handleMessage()收到消息后主要调用了handleLaunchActivity()方法继续处理:
handleLaunchActivity()方法首先调用了performLaunchActivity()方法,这个方法主要用于创建Application Context和Activity Context。之后调用handleResumeActivity()方法主要是来进入Activity的生命周期onResume()方法。下面看看performLaunchActivity()方法创建Application Context的过程:
变量packageInfo是一个LoadApk类型的对象,通过调用它的makeApplication()方法来创建Application Context。在该方法中,如果变量Activity不为空,还会调用createBaseContextForActviity()方法来创建Activity上下文Context。下面是LoadApk类中的makeApplication()方法来创建Application Context:
变量mApplication是LoadApk类中的全局变量,它是一个Application对象。假设第一次启动应用程序时,Application Context还没创建,会先创建一个ContextImpl实例,然后会通过ActivityThread的变量mInstrumentation(Instrumentation类型对象)的方法newApplication()创建一个Application对象app。然后把app对象通过setOuterContext()方法赋值给ContextImpl的mOuterContext变量,最后把该app对象赋值给LoadApk的人全局变量mApplication。
下面看看Instrumentation类的newApplication方法:
newApplication()方法首先会创建一个Application类型的对象app,然后调用它的attach()方法将传进来的ContextImpl对象赋值给ContextWrapper类的mBase对象,最后返回app。
下面看看Application类的attach()方法:
|
|
attach()方法调用父类的attachBaseContext()方,将ContextImpl对象赋值给ContextWrapper类的mBase对象。
回到前面的makeApplication()方法中,这个过程之后会调用setOuterContext()方法将Application对象赋值给ContextImpl的mOuterContext变量:
至此,Application Context的创建过程就介绍完毕。
获取·Application Context
在应用程序中,可以直接通过getApplicationContext()方法来获得ApplicationContext。而这个调用,会进入到框架层ContextWrapper类的getApplicationContext()方法中:
变量mBase是COntextImpl类的对象,此处调用getApplicationContext()方法进入COntextImpl类的getApplicationContext()方法中:
变量mPackageInfo是一个LoadApk对象,而变量mMainThread是一个ActivityThread对象。由于应用程序已经启动,mPackageInfo变量不为空,于是调用LoadApk的个体Application方法:
直接返回Application类型的mApplication对象,在前面LoadApk.java的makeApplication()方法中创建的。
Activity Context创建过程
前面的创建调用过程和Application的创建基本一致,都是由AMS服务调用scheduleLaunchActivity()方法开始,到performLaunchActivity()方法:
大致流程可分为一下几个步骤:
变量cl是一个ClassLoader对象,即类加载器。通过Instrumentation对象的newActivity()方法创建一个Activity实例。
123456public Activity newActivity(ClassLoader cl, String className,Intent intent)throws InstantiationException, IllegalAccessException,ClassNotFoundException {return (Activity)cl.loadClass(className).newInstance();}接着performLaunchActivity()方法调用createBaseContextForActivity()方法来创建ContextImpl类型对象appContext:
12345678private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {.....ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token, displayId, r.overrideConfig);appContext.setOuterContext(activity);Context baseContext = appContext;......}
通过调用ContextImpl的createActivityContext()方创建出一个ContextImpl实例,并通过ContextImpl的setOuterContext()方法将前面创建的activity实例对象赋值给ContextImpl类的mOuterContext变量。如下所示:
|
|
接着performLaunchActivity()方法就调用Activity的attach()方法来讲前面所创建的ContextImpl对象appContext保存在Activity内部:
1234567891011121314151617181920212223242526272829303132333435363738final 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) {//调用父类的方法设置mBase,与上文Application类似attachBaseContext(context);mFragments.attachHost(null /*parent*/);mWindow = new PhoneWindow(this, window);mWindow.setWindowControllerCallback(this);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);}mUiThread = Thread.currentThread();mMainThread = aThread;........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;}最后performLaunchActivity()方法又通过调用mInstrumentation对象的方法callActivityOnCreate()来通知Activity进入它的生命周期onCreate()方法:
123456public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {prePerformCreate(activity);activity.performCreate(icicle, persistentState);postPerformCreate(activity);}
通过调用Activity的performCreate()方法:
根据java的多态性,onCreate()会进入Activity子类的onCreate()方法。
Service Context的创建过程
service在启动过程中,ActivityManagerService服务会被调用到ActivityThread类中,最后进入ActivityThread的handleCreateService()方法:
handleCreateService()方法首先加载一个ClassLoader对象,通过这个对象加载Service对象,构建Service实例。接着通过ContextImpl的createAppContext()方法创建ContextImpl类型实例context。然后通过这个ContextImpl类型实例context调用setOuterContext()方法把Service对象赋值给ContextImpl的mOuterContext变量。最后又通过调用Service的attach()方法把ContextImpl实例context赋值给ContextWrapper类的mBase变量。该过程和上面的两种基本相似,这里就不一一展开咯。。。。。