类继承图
我们来看下关于 Context 的类继承图,我们通过查看源码得知,Context 是一个抽象类,所以它肯定有其实现类,查阅得知它的实现类为 ContextWrapper 和 ContextImpl ,所以它的继承图如下:
以上的 Context 类继承关系清晰简洁,可以得知,Application 、 Service 、Activity 都是继承的 Context 类,所以从这里我们可以得知:
Context 数量 = Activity 数量 + Service 数量 + 1
另外,我们可以看到 Application 和 Service 都是直接继承 ContextWrapper 的而 Activity 却是继承 ContextThemeWrapper 的,这是为何?其实 ContextThemeWrapper 是关于主题类的,Activity 是有界面的,而 Application 和 Service 却没有。接下来我们来详细看下它们的源码实现。
ContextWrapper
我们进入到 ContextWrapper 源码中可以发现,它其实调用了 mBase 里面的方法,而 mBase 其实是 ContextImpl ,所以最终还是得调用它的实现类 ContextImpl 类里面的方法。
public class ContextWrapper extends Context {
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
//其余的都是覆盖Context里面的方法
}
我们可以按照上面的类的继承图进行依次分析,由上面可以知道 ContextWrapper 其实是调用 ContextImpl 里面的方法,所以 Application 和 Service 还有 Activity 它们应该都跟 ContextImpl 有关的。到底是不是这样的呢?我们追踪源码进行分析。
Application
类似于 Java 的 main 启动方法程序,Android 也有一个类似的方法,那就是在 ActivityThread 类中也有一个 main ,这是开始的地方,我们从这里进行一点一点跟踪:
ActivityThread#main
//省略部分代码...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
//省略部分代码...
Looper.loop();
//省略部分代码...
我们找到 ActivityThread 的 main 方法,省略无关代码,这个 main 方法就是不断的从消息队列中获取消息,然后进行处理。我们本次不分析 Looper 相关的东西,只分析跟 Context 有关的内容,继续进入 attach 方法,
Android 分析源码,不能一头扎进去,我们应该主要分析它的流程。
ActivityThread#attach
//省略部分代码...
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
//Application的实例创建
mInitialApplication = context.mPackageInfo.makeApplication