二、 什么时候创建Context实例
熟悉了Context的继承关系后,我们接下来分析应用程序在什么情况需要创建Context对象的?应用程序创建Context实例的
情况有如下几种情况:
1、创建Application 对象时, 而且整个App共一个Application对象
2、创建Service对象时
3、创建Activity对象时
因此应用程序App共有的Context数目公式为:
总Context实例个数 = Service个数 + Activity个数 + 1(Application对应的Context实例)
具体创建Context的时机
1、创建Application对象的时机
每个应用程序在第一次启动时,都会首先创建Application对象。如果对应用程序启动一个Activity(startActivity)流程比较
清楚的话,创建Application的时机在创建handleBindApplication()方法中,该函数位于 ActivityThread.java类中 ,如下:
//创建Application时同时创建的ContextIml实例
privatefinalvoidhandleBindApplication(AppBindData data){
...
///创建Application对象
Application app = data.info.makeApplication(data.restrictedBackupMode,null);
...
}
publicApplication makeApplication(booleanforceDefaultAppClass, Instrumentation instrumentation) {
...
try{
java.lang.ClassLoader cl = getClassLoader();
ContextImpl appContext =newContextImpl();//创建一个ContextImpl对象实例
appContext.init(this,null, mActivityThread);//初始化该ContextIml实例的相关属性
///新建一个Application对象
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);//将该Application实例传递给该ContextImpl实例
}
...
}
2、创建Activity对象的时机
通过startActivity()或startActivityForResult()请求启动一个Activity时,如果系统检测需要新建一个Activity对象时,就会
回调handleLaunchActivity()方法,该方法继而调用performLaunchActivity()方法,去创建一个Activity实例,并且回调
onCreate(),onStart()方法等, 函数都位于 ActivityThread.java类 ,如下:
//创建一个Activity实例时同时创建ContextIml实例
privatefinalvoidhandleLaunchActivity(ActivityRecord r, Intent customIntent) {
...
Activity a = performLaunchActivity(r, customIntent);//启动一个Activity
}
privatefinalActivity performLaunchActivity(ActivityRecord r, Intent customIntent) {
...
Activity activity =null;
try{
//创建一个Activity对象实例
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
}
if(activity !=null) {
ContextImpl appContext =newContextImpl();//创建一个Activity实例
appContext.init(r.packageInfo, r.token,this);//初始化该ContextIml实例的相关属性
appContext.setOuterContext(activity);//将该Activity信息传递给该ContextImpl实例
...
}
...
}