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
对象相互引用
评论