10

我只是出于兴趣而研究了Android资源。我发现这Context是一个带有抽象方法的抽象类:

public abstract Context getApplicationContext();

导致方法实现的ContextWrapper.java扩展:Context.javagetApplicationContext()

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

但是是对在 的构造函数中初始化mBase的类型的对象的引用:ContextContextWrapper

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

所以这个mBase引用是指abstract类?好吧,我只是不明白当您getApplicationContext()Activity.

4

1 回答 1

15

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

只要您的baseextends Context,它就必须提供 的实现getApplicationContext(),在这种情况下,ContextWrapper就是您在此处提供的代码。有这个实现,ContextImpl.

阅读您提供的代码时,请务必注意几件事: ContextWrapper它本身 extends Context,但它也需要 aContext作为输入(可以是 a ContextWrapper,或 a Service,或 an Application,或 an Activity)。 ContextWrapper不在乎是哪一种;它只知道他们有一个方法getApplicationContext,并且它想在被问到时调用该方法。(例如,它可以被传递 another ContextWrapper,但因为 said在其构造函数中ContextWrapper也需要 a Context,所以只会添加另一层嵌套。)

Application extends ContextWrapper类调用,这super(null)意味着如果以这种方式保留它getApplicationContext()会抛出 a ——但是,它也可以由设置,这就是它变得有趣的地方。NullPointerExceptionContextWrapperattachBaseContext(Context)

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

  • Instrumentation课程中,您会发现创建android.app.Instrumentation.newApplication()aContextImpl并将其传递给Application.
  • ActivityThread课堂上,您会发现handleBindApplicationwhich 创建了作为其 rootContextImpl传递给的a 。ActivityContext
  • LoadedApk课堂上,您会发现makeApplicationwhich 创建了一个ContextImpl传递给一个Application. 这里是它被称为的地方。

因此,在一天mBase结束时,通常以ContextImpl.

我在发现所有这些时查看了潜在有用的链接:

于 2012-08-22T18:46:59.847 回答