调用getApplicationContext()时调用的代码在哪里?

时间:2012-08-22 18:34:31

标签: android

我只是出于兴趣而调查了Android sources。我发现Context是一个抽象类,抽象方法:

public abstract Context getApplicationContext();

导致ContextWrapper.java方法实施的Context.java扩展getApplicationContext()

 @Override
    public Context getApplicationContext() {
        return mBase.getApplicationContext();
    }

mBase是对Context类型的对象的引用,该对象在ContextWrapper的构造函数中初始化:

public ContextWrapper(Context base) {
    mBase = base;
}

所以这个mBase引用是指abstract类吗? 好吧,我只是不明白当你从getApplicationContext()拨打Activity时执行的代码在哪里。

1 个答案:

答案 0 :(得分:15)

这是多态性的一个有趣例子。

只要您的base扩展Context,就必须提供getApplicationContext()的实施,在ContextWrapper的情况下,您需要提供此处提供的代码。有这个实现,the one in ContextImpl

在阅读您提供的代码时,请务必注意以下几点:ContextWrapper本身扩展Context,但它也需要Context作为输入(可能是{ {1}},或ContextWrapperServiceApplication)。 Activity并不关心它是哪种类型;它只知道他们有一个方法ContextWrapper,它想在被问到时调用该方法。 (例如,它可以传递给另一个getApplicationContext,但因为所谓的ContextWrapper在其构造函数中也需要ContextWrapper,这只会增加另一级别的嵌套。)

Context班级调用Application extends ContextWrapper,这意味着super(null)如果将其留下getApplicationContext()将会抛出NullPointerException - 但是,ContextWrapper它也可以由attachBaseContext(Context)设置,这就是它变得有趣的地方。

ActivityApplication都有方法attach(Context [...other stuff])。他们每个人都使用传入的attachBaseContext()调用Context

  • Instrumentation课程中,您会找到android.app.Instrumentation.newApplication(),其中ContextImpl已创建,并传递到Application
  • ActivityThread课程中,您会找到handleBindApplication,其中ContextImpl会将Activity作为其根Context传递给LoadedApk
  • makeApplication课程中,您会找到ContextImpl,其中Application会传递给mBaseHere是它所称的地方。

因此,在一天结束时,ContextImpl通常最终为{{1}}。

我在查找所有这些内容时看到的潜在有用链接: