系统Context的类图
从上面的图可以看到,Activity
和ContextImpl
并没有直接的继承关系,而我们知道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
对象类型就是ContextImpl
。Activity
成功与ContextImpl
联系起来了!
上面的说明有点逆向,用时间顺序来说的话,就是应用启动过程在performLaunchActivity中创建了ContextImpl类型的mBase变量,然后将mBase attach到Activity中,然后应用调用getSystemService的时候,会逐步调用到mBase的getSystemService方法,即ContextImpl类的getSystemService方法。
代码分析基于kk