Activity 的创建流程
追溯到 ActivityThread.java
的 performLaunchActivity
方法:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { //1. 获取LoadedApk对象 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); } ....... //2.创建 ContextImpl 对象 appContext ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null; try { java.lang.ClassLoader cl = appContext.getClassLoader(); //3. 创建 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) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to instantiate activity " + component + ": " + e.toString(), e); } } try { //4. 创建Application 对象 app Application app = r.packageInfo.makeApplication(false, mInstrumentation); ........ //appContext 我们知道是ContextImpl类的对象 ,将activity 设置进去 appContext.setOuterContext(activity); //appContext window相联合绑定 activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigpurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback); ...... activity.mCalled = false; if (r.isPersistable()) { //5. 调用 activity 的 onCreate 方法 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } ........ return activity; }复制代码
1.获取
LoadedApk
对象 2.创建ContextImpl
对象appContext
3.创建Activity
对象activity
4.创建Application
对象app
5.调用activity
的onCreate
方法启动
Service 创建流程
service
创建和 activity
的创建类似。 ActivityThread.java
的 handleCreateService
方法:
private void handleCreateService(CreateServiceData data) { ..... //1. 获取LoadedApk 对象 LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); //2.创建 service 对象 Service service = null; try { java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); } catch (Exception e) { .... } try { ..... // 3. 创建ContextImpl 对象 context ContextImpl context = ContextImpl.createAppContext(this, packageInfo); context.setOuterContext(service); //4. 创建Application对象 app Application app = packageInfo.makeApplication(false, mInstrumentation); service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService()); //5.调用 service 的 onCreate 方法 service.onCreate(); mServices.put(data.token, service); ..... } catch (Exception e) { ...... } }复制代码
1.获取
LoadedApk
对象 2.创建service
对象 3.创建ContextImpl
对象 context 4.创建Application
对象 app 5.调用Service
的onCreate
方法
Application
最终通过 Instrumentation.java
的 newApplication()
方法创建完成:
static public Application newApplication(Class clazz, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Application app = (Application)clazz.newInstance(); app.attach(context); return app; }复制代码
这里我们发现 ContextImpl
的 setOuterContext
中设置 context
的不同:
performLaunchActivity
------activity
//appContext 就是ContextImpl 实例对象appContext.setOuterContext(activity);复制代码
makeApplication
-----application
Application app = null;.....appContext.setOuterContext(app);复制代码
handleCreateService
----service
context.setOuterContext(service);复制代码
Activity context 的创建
ContextImpl appContext = createBaseContextForActivity(r);private ContextImpl createBaseContextForActivity(ActivityClientRecord r) { .... //创建appContext, 将应用的若干信息传进去 ContextImpl appContext = ContextImpl.createActivityContext( this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig); .... return appContext; }复制代码
static ContextImpl createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration) { ..... //将信息传入 ContextImpl 中 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName, activityToken, null, 0, classLoader); // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY. displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY; final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY) ? packageInfo.getCompatibilityInfo() : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; final ResourcesManager resourcesManager = ResourcesManager.getInstance(); // Create the base resources for which all configuration contexts for this Activity // will be rebased upon. //设置 resources context.setResources(resourcesManager.createBaseActivityResources(activityToken, packageInfo.getResDir(), splitDirs, packageInfo.getOverlayDirs(), packageInfo.getApplicationInfo().sharedLibraryFiles, displayId, overrideConfiguration, compatInfo, classLoader)); context.mDisplay = resourcesManager.getAdjustedDisplay(displayId, context.getResources()); return context; }复制代码
Service context 创建
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);复制代码
createAppContext
方法:
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null); context.setResources(packageInfo.getResources()); return context; }复制代码
以上是针对这个 Activity
和 Service
与 Context
之间的联系做了查看。