Context个人笔记
Context是什么?
我理解的Context是:
Android系统给程序发放的一个权限凭证,有了这个凭证你才能做某些事情,而且这个凭证分多种(Application、Service、Activity),不同类型的凭证做不同的事情
在代码里面的Context
是一个接口,它定义了android系统服务可以为android程序提供哪些系统服务,它的具体实现类是ContextImpl
,但是,Application、Activity、Service继承的Context都不是ContextImpl,而是ContextWrapper,ContextWrapper通过持有一个mBase(实际被赋值为ContextImpl,后续会讲到),将具体的操作逻辑转接到ContextImpl(这里主要是装饰器模式)
Application以及四大组件Context来源(代码基于Android Q版本
)
1、Application
以启动Activity为例子
在启动过程中,调用到ActivityStackSuperVisor
的startSpecificActivityLocked
的时候发现没有进程,就会去调用startProcessLocked
,然后新建进程,新建完进程进入ActivityThread
的handleBindApplication
,调用LoadedApk去新建一个ContextImpl
,在创建Application
的过程中会通过Instrumentation
去创建Application
//ActivityThread#handleBindApplication
Application app;
...
try {
//data.info是一个loadedApk对象
app = data.info.makeApplication(data.restrictedBackupMode, null);
...
//这个也重要,这个就是我们调用 getApplicationContext 得到的其中一种情况,另外一种是
//LoadedApk的内部变量,下面会讲
mInitialApplication = app;
//如果有ContentProvider的话,创建ContentProvider,注意此时Application的onCreate还没调用
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.providers);
}
}
}
try {
//创建完后通过Instrumentation分发Application的生命周期
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
}
...
//LoadedApk#makeApplication
try {
java.lang.ClassLoader cl = getClassLoader();
...
//新建ContextImpl
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
//将它保存在ContextImpl的变量里面
appContext.setOuterContext(app);
} catch (Exception e) {
}
//ContextImpl#setOuterContext
final void setOuterContext(Context context) {
mOuterContext = context;
}
//Instrumentation#newApplication
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
//真正创建了Application的地方
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
//创建完之后调用attach,在这里将ContextImpl保存到ContextWrapper的mBase里面,Activity也是同样
//的套路
app.attach(context);
return app;
}