在android中, Context表示运行时上下文,其类图为:
由图中可以看到Activity、Service、Application都是继承ContextWrapper,而ContextWrapper类实现了Context接口。其中ContextWrapper是Context的包装类,真正的实现类为ContextIml,ContextWrapper类有个成员变量:
public class ContextWrapper extends Context {
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
/**
* Set the base context for this ContextWrapper. All calls will then be
* delegated to the base context. Throws
* IllegalStateException if a base context has already been set.
*
* @param base The new base context for this wrapper.
*/
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
其中mBase为ContextIml类的实例,ContextImpl类有内部类ServiceFetcher和StaticServiceFetcher类,
/*package*/ static class ServiceFetcher {
int mContextCacheIndex = -1;
/**
* Main entrypoint; only override if you don't need caching.
*/
public Object getService(ContextImpl ctx) {
ArrayList<Object> cache = ctx.mServiceCache;
Object service;
synchronized (cache) {
if (cache.size() == 0) {
// Initialize the cache vector on first access.
// At this point sNextPerContextServiceCacheIndex
// is the number of potential services that are
// cached per-Context.
for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
cache.add(null);
}
} else {
service = cache.get(mContextCacheIndex);
if (service != null) {
return service;
}
}
service = createService(ctx);
cache.set(mContextCacheIndex, service);
return service;
}
}
这个代码里面, 首先会去mServiceCache里面去取,如果缓存里面没有,那么会调用createService创建一个service,然后添加缓存里面,然后返回。其中createService()是一个抽象方法,需要子类去实现。ContextImpl构造方法如下:
public ContextImpl(ContextImpl context) {
mPackageInfo = context.mPackageInfo;
mBasePackageName = context.mBasePackageName;
mOpPackageName = context.mOpPackageName;
mResources = context.mResources;
mMainThread = context.mMainThread;
mContentResolver = context.mContentResolver;
mUser = context.mUser;
mDisplay = context.mDisplay;
mOuterContext = this;
mDisplayAdjustments.setCompatibilityInfo(mPackageInfo.getCompatibilityInfo());
}
就是对成员变量进行赋值。
在app启动的时候,会去创建一个ApplicationContext,代码在ActivityThread收到BIND_APPLICATION消息的时候,
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
在这里,首先会去取携带的AppBindData数据,然后调用handleBindApplication()方法, 在handleBindApplication()方法里面,会去调用makeApplication()方法进行初始化,
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
ContextImpl appContext = new ContextImpl();
appContext.init(this, null, mActivityThread);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
return app;
}
在这个方法里面,创建了ContextImpl实例和Application实例。