[转]Context是如何跟ContextImpl关联的

系统Context的类图
在这里插入图片描述

从上面的图可以看到,ActivityContextImpl并没有直接的继承关系,而我们知道Activity的主要处理逻辑都在ContextImpl里面。下面我们看看是怎么一步步引用到ContextImpl的。

Activity获取系统服务getSystemService()为例简单说一下

frameworks/base/core/java/android/app/Activity.java

@Override
public Object getSystemService(@ServiceName @NonNull String name) {
    ...
    return super.getSystemService(name);
}

super.getSystemService(name)会进入父类的getSystemService()方法,父类由上面的类图可以知道是ContextThemeWrapper
frameworks/base/core/java/android/view/ContextThemeWrapper.java

private Context mBase;

@Override 
public Object getSystemService(String name) {
    if (LAYOUT_INFLATER_SERVICE.equals(name)) {
        if (mInflater == null) {
            mInflater = LayoutInflater.from(mBase).cloneInContext(this);
        }
        return mInflater;
    }
    return mBase.getSystemService(name);
}

如果不是LAYOUT_INFLATER_SERVICE的话,会进入mBase.getSystemService(name);,而mBase的赋值是调用的ContextThemeWrapper中的attachBaseContext()方法

@Override 
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(newBase);
    mBase = newBase;
}

attachBaseContext()方法是在Activity类被attach()方法调用

final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
    ...
    attachBaseContext(context);
    ...
}

这个方法是在ActivityThread类中的performLaunchActivity()方法调用,performLaunchActivity()方法用于启动Activity,所以mBase对象是在应用启动的时候初始化的。

frameworks/base/core/java/android/app/ActivityThread.java

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
            ......
            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config);
            ...

}

马上就能知道这个mBase对象是什么了,看看createBaseContextForActivity函数

private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
        ContextImpl appContext = new ContextImpl();
        ...
        Context baseContext = appContext;
        return baseContext;
}

看到了吧,createBaseContextForActivity返回的是ContextImpl类型的对象。所以mBase对象类型就是ContextImplActivity成功与ContextImpl 联系起来了!

上面的说明有点逆向,用时间顺序来说的话,就是应用启动过程在performLaunchActivity中创建了ContextImpl类型的mBase变量,然后将mBase attach到Activity中,然后应用调用getSystemService的时候,会逐步调用到mBase的getSystemService方法,即ContextImpl类的getSystemService方法。
在这里插入图片描述

代码分析基于kk

参考文章:
https://www.jianshu.com/p/db2457cf7e00

猜你喜欢

转载自blog.csdn.net/QWE123ZXCZ/article/details/84617118
今日推荐