Android 面试:一个进程有多少个 -Context- 对象?看似初级的问题
private void handleBindApplication(AppBindData data) {// ...Application app;// data.info 为 LoadedApk.javaapp = data.info.makeApplication(data.restrictedBackupMode, null);// ...mInitialApplication = app;// ...}
// LoadedApk.java
private Application mApplication;
public Application makeApplication(...) {// 创建基础对象 ContextImplContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);// 反射调用创建 Application 对象 app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);// ContextImpl 也持有包装类 ApplicationappContext.setOuterContext(app);// 保存创建的 Application 对象 mActivityThread.mAllApplications.add(app);mApplication = app;}
// Instrumentation.java
public Application newApplication(ClassLoader cl, String className, Context context) {// 反射调用创建 Application 对象 Application app = getFactory(context.getPackageName()).instantiateApplication(cl, className);app.attach(context);retur
n app;}
// Application.javafinal void attach(Context context) {// 设置包装类 Application 的基础对象 attachBaseContext(context);mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;}
总结要点如下:
- 一个 - Application对象相当于存在两个- Context对象(代理对象与基础对象)
- Application对象与- ContextImpl对象相互引用
3. Activity 对象
这一节我们来看Activity对象的创建过程,简单来说:
- 创建 - Application对象之后,最后在- ActivityThread#handleLaunchActivity(...)中创建- Activity对象
// ActivityThread.java
public Activity handleLaunchActivity(...) {// ...final Activity a = performLaunchActivity(r, customIntent);// ...}
private Activity performLaunchActivity(...) {// ...// 创建基础对象 ContextImplContextImpl appContext = ContextImpl.createActivityContext(...);// 反射调用创建 Activity 对象 Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);// 相互引用 appContext.setOuterContext(activity);activity.attach(appContext,...)// ...}
总结要点如下:
- 一个 - Activity对象相当于存在两个- Context对象(代理对象与基础对象)
- Activity对象与- ContextImpl对象相互引用
4. Service 对象
这一节我们来看Service对象的创建过程,简单来说:
- 创建 - Application对象之后,- startService(...)最后在- ActivityThread#handleCreateService(...)中创建- Service对象
- 创建 - Application对象之后,- bindService(...)最后在- ActivityThread#handleCreateService(...)中创建- Service对象,在- ActivityThread#handleBindService(...)中绑定- Service(注意:两个方法都在远程进程执行)
// ActivityThread.java
private void handleCreateService(...) {// ...// 反射调用创建 Serivce 对象 Serivce service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);// 创建基础对象 ContextImplContextImpl context = ContextImpl.createAppContext(this, packageInfo);// 相互引用 context.setOuterContext(service);service.attach(...);}
总结要点如下:
- 一个 - Serivce对象相当于存在两个- Context对象(代理对象与基础对象)
- Serivce对象与- ContextImpl对象相互引用











 
    
评论