目录
- 简介
- Context类图
- 源码中Context创建
- Application
- Activity
- Service
- BroadcastReceiver
- ContentProvider
- Context使用
- 普通Context
- de/ce
1. 简介
在Android开发中少不了要跟Context打交道,比如启动activity,启动service等。但是又很难表述这个context到底是个什么东西,从字面意思来看应该叫做“上下文”,确实在开发过程中这个context也给人感觉无处不在,但又非常抽象,难以把握实质。其实产生这样感觉的原因是我们大部分的开发都在跟组件打交道,组件与Context又有着密不可分的关系。
2. Context类图
从上面这个图大致可以看出来一些信息:
- Context本身是一个抽象类,定义了很多common的抽象方法
- ContextImpl和ContextWrapper是具体的实现类
- ContextWrapper中持有ContextImpl类型的mBase对象
- Application和Service都是ContextWrapper的子类
- BraodcastReceiver不是ContextWrapper的子类但是有一个ReceiverRestrictedContext
- 对于Activity而言,由于涉及到theme和window,其父类为ContextThemeWrapper,而ContextThemeWrapper的父类也是ContextWrapper
- 日常熟悉的startActivity/startService等对于组件常用的方法在抽像类中就已经定义,在ContextWrapper中实现
- 用到了装饰模式,ContextWrapper中通过ComtextImpl对象实现真正的操作
3. 源码中Context创建
3.1 Application
每个app的进程在创建之后,在ActivityThread的handleBindApplication中会去通过LoadedApk创建Application。
LoadedApk:可以认为是应用的apk在进程中对应的对象,每个apk在每个进程中只创建一次
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
// 创建application的contextImpl对象
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 通过反射创建Application对象
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
...
return app;
}
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
// Application.attach
/* package */ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
// ContextWrapper.attachBaseContext
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
这里可以看到
- 先是通过ContextImpl的静态方法创建了ContextImpl对象
- 随后通过反射创建了真正的application对象
- 在newApplication中会逐级调用,到