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

Eug*_*ene 10 android

我已研究过的Android 只是出于兴趣.我发现这Context是一个抽象类的抽象方法:

public abstract Context getApplicationContext();
Run Code Online (Sandbox Code Playgroud)

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

 @Override
    public Context getApplicationContext() {
        return mBase.getApplicationContext();
    }
Run Code Online (Sandbox Code Playgroud)

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

public ContextWrapper(Context base) {
    mBase = base;
}
Run Code Online (Sandbox Code Playgroud)

所以这个mBase参考指的是abstract班级?好吧,我只是不明白的地方是,当你打电话时执行的代码getApplicationContext()从你的Activity.

Jon*_*n O 15

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

只要你base扩展Context,就必须提供一个实现getApplicationContext(),在这种情况下ContextWrapper你就是这里提供的代码.有这个实现,以及中的那个ContextImpl.

读你所提供的代码时需要注意的几件事情是很重要的: ContextWrapper本身延伸Context,但它也需要一个Context作为输入(可以是一个ContextWrapper,或者Service,或者Application,或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()a的地方ContextImpl,并将其传递给Application.
  • ActivityThread类中,您将找到handleBindApplication哪个创建一个ContextImpl传递给Activity它的根Context.
  • LoadedApk课堂上,你会发现makeApplication哪个创建了一个ContextImpl传递给一个Application. 以下是它所称的地方.

因此,在一天mBase结束时,通常最终会成为一个ContextImpl.

在找到所有这些时,我看到了潜在有用的链接: