写点什么

Android 面试:一个进程有多少个 -Context- 对象?看似初级的问题,答的好的人确不多

用户头像
Android架构
关注
发布于: 1 小时前

目录


作者:彭旭锐链接:https://www.jianshu.com/p/51d63a1ffb95

1. Context 继承关系

Context是一个抽象类,具体的实现类有ApplicationActivityServiceContextImpl。为方便区分,通常也称为ApplicationConextActivityContextServiceContext,具体 UML 类图如下:



可以看到,除了我们熟悉的ApplicationActivityService,继承关系上还有ContextWrapperContextThemeWrapper,它们的作用 & 职责如下:


  • ContextWrapper

  • 定义:Context包装类

  • 作用:持有基础对象的引用(mBase),并且实现了Context接口,将所有方法调用请求转发给基础对象


// ContextWrapper.java


Context mBase;


public ContextWrapper(Context base) {mBase = base;}


// 【分析点 1:绑定基础对象(见 todo)】protected void attachBaseContext(Context base) {if (mBase != null) {throw new IllegalStateException("Base context


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


already set");}mBase = base;}


@Overridepublic void startActivity(Intent intent) {// 转发给 mBasemBase.startActivity(intent);}


  • ContextThemeWrapper

  • 定义:Context包装类【todo】



2. Application 对象

我们都知道,在启动四大组件(Activity、Service、ContentProvider, BroadcastReceiver)时,如果对应的进程未启动,就需要先创建进程,相应地也会创建一个Application对象。简单来说:


  • system_server进程,通过AMS#getProcessRecordLocked(...)获取进程信息(ProcessRecord)

  • 若不存在,则调用AMS#startProcessLocked(...)创建进程

  • Zygote孵化目标进程之后,在目标进程反射执行ActivityThread#main(),并最终在ActivityThread#handleBindApplication(...)中创建Application对象


// ActivityThread.java


Application mInitialApplication;final ArrayList<Application> mAllApplications = new ArrayList<Application>();


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);return 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);

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android面试:一个进程有多少个-Context-对象?看似初级的问题,答的好的人确不多