Android全面解析之Context机制

什么是Context

应用程序和系统之间的桥梁,应用程序访问系统各种资源的接口。

Context家族

06GYuD.png

这里运用到了一种模式:装饰者模式

Context的创建过程

Application

0c5r3n.png
ActivityThread.class (api29)

private void handleBindApplication(AppBindData data) {
    ...
    // 创建LoadedApk对象
    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
    ...
    Application app;
    ...
    try {
        // 创建Application
        app = data.info.makeApplication(data.restrictedBackupMode, null);
        ...
    }
    try {
        ...
        // 回调Application的onCreate方法
        mInstrumentation.callApplicationOnCreate(app);
    }
    ...
}
LoadeApk.class(api29)
public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    // 如果application已经存在则直接返回
    if (mApplication != null) {
        return mApplication;
    }
    ...
    Application app = null;
    String appClass = mApplicationInfo.className;
    ...
    try {
        java.lang.ClassLoader cl = getClassLoader();
       ...
        // 创建ContextImpl
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        // 利用类加载器加载我们在AndroidMenifest指定的Application类
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        // 把Application的引用给comtextImpl,这样contextImpl也可以很方便地访问Application
        appContext.setOuterContext(app);
    } 
    ...
    mActivityThread.mAllApplications.add(app);
    // 把app设置为mApplication,当我们调用context.getApplicationContext就是获取这个对象
    mApplication = app;

    if (instrumentation != null) {
        try {
            // 回调Application的onCreate方法
            instrumentation.callApplicationOnCreate(app);
        } 
        ...
    }
    ...
    return app;
}

代码的逻辑也不复杂,首先判断LoadedApk对象中的mApplication是否存在,否则创建ContextImpl,再利用类加载器和contextImpl创建Application,最后把Application对象赋值给LoadedApk的mApplication,再回调Application的onCreate方法。

contextImpl是如何创建的:

ContextImpl.class(api29)
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
        String opPackageName) {
    if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
            null, opPackageName);
    context.setResources(packageInfo.getResources());
    return context;
}

Activity

Activity的context也是在Activity创建的过程中被创建的,这个就涉及到Activity的启动流程,这里涉及到三个流程:应用程序请求AMS,AMS处理请求,应用程序响应Activity创建事务:

aYQwF0.png

Service

afbYYq.png

Broadcast

dnSOMQ.png

ContentProvider

0gYQXV.png

参考:

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容