简体   繁体   English

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

[英]Where is the code which is called when you call getApplicationContext()?

I have looked into Android sources just out of interest. 我已研究过的Android 只是出于兴趣。 What I found is that Context is an abstract class with abstract method: 我发现Context是一个抽象类,带有抽象方法:

public abstract Context getApplicationContext();

The ContextWrapper.java extends Context.java which led to implementation of getApplicationContext() method: ContextWrapper.java扩展了Context.java ,导致了getApplicationContext()方法的实现:

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

But mBase is reference to an object of type Context which is initialized in ContextWrapper 's constructor: 但是mBase是对Context类型的对象的引用,它在ContextWrapper的构造函数中初始化:

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

So this mBase reference refers to abstract class? 那么这个mBase引用是指abstract类? Well, I just don't understand where is the code which is executed when you call getApplicationContext() from your Activity . 好吧,我只是不明白从Activity调用getApplicationContext()时执行的代码在哪里。

This is an interesting example of polymorphism. 这是多态性的一个有趣例子。

As long as your base extends Context , it has to provide an implementation of getApplicationContext() , which in the case of ContextWrapper is the code you provided here. 只要您的base扩展了Context ,它就必须提供getApplicationContext()的实现,在ContextWrapper的情况下, ContextWrapper是您在此处提供的代码。 There's this implementation, and the one in ContextImpl . 这是一个实现,也是ContextImpl

It's important to note a couple of things when reading the code you provided: ContextWrapper itself extends Context , but it also takes a Context as an input (which could be a ContextWrapper , or a Service , or an Application , or an Activity ). 在阅读您提供的代码时需要注意几件事情很重要: ContextWrapper本身扩展了Context ,但它也将Context作为输入(可以是ContextWrapper ,或Service ,或Application ,或Activity )。 ContextWrapper doesn't care which kind it is; ContextWrapper并不关心它是哪种类型; it just knows that they have a method getApplicationContext and it wants to call that method when asked. 它只知道他们有一个方法getApplicationContext并且它想在被问到时调用该方法。 (For example, it could be passed another ContextWrapper , but because said ContextWrapper would also require a Context in its constructor, that would just add another level of nesting.) (例如,它可以传递给另一个ContextWrapper ,但是因为所述ContextWrapper在其构造函数中也需要一个Context ,这只会增加另一个嵌套级别。)

The Application extends ContextWrapper class calls super(null) , which would mean that getApplicationContext() would throw a NullPointerException if it were left that way--however, in ContextWrapper it's also settable by attachBaseContext(Context) , and this is where it gets interesting. Application extends ContextWrapper类调用super(null) ,这意味着getApplicationContext()会抛出NullPointerException如果它被保留的话 - 但是,在ContextWrapper它也可以通过attachBaseContext(Context) ,这就是它变得有趣的地方。

Both Activity and Application have methods attach(Context [...other stuff]) . ActivityApplication都有方法attach(Context [...other stuff]) Each of them calls attachBaseContext() with the passed-in Context . 它们中的每一个都使用传入的Context调用attachBaseContext()

  • In the Instrumentation class, you'll find android.app.Instrumentation.newApplication() , where a ContextImpl is created, and passed into an Application . Instrumentation类中,您将找到android.app.Instrumentation.newApplication() ,其中创建了ContextImpl ,并将其传递给Application
  • In the ActivityThread class, you'll find handleBindApplication which creates a ContextImpl that gets passed to the Activity as its root Context . ActivityThread类中,您将找到handleBindApplication ,它创建一个ContextImpl ,它作为根Context传递给Activity
  • In the LoadedApk class, you'll find makeApplication which creates a ContextImpl that gets passed to an Application . LoadedApk类中,您将找到makeApplication ,它创建一个传递给ApplicationContextImpl Here are the places it's called. 以下是它所称的地方。

So, at the end of the day, mBase typically ends up as a ContextImpl . 因此,在一天结束时, mBase通常最终成为ContextImpl

Potentially useful links I looked at while finding all of this out: 在找到所有这些时,我看到了潜在有用的链接:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 什么时候调用Application类的getApplicationContext()? - When is getApplicationContext() of Application class called? 哪种方法更好地编码getActivity()和getApplicationContext()? - Which is a better way to code getActivity() , getApplicationContext()? 调用getApplicationContext如何返回在应用程序中使用的上下文类型? - How is the call getApplicationContext which returns a context type used in applications? 从J单元测试用例调用时,getApplicationContext()返回null - getApplicationContext() returns null when called from J Unit Test Case 当我调用 startActivity(i) 时显示错误(见下文)我的代码是 Intent i=new Intent(getApplicationContext(),NewRecipe.class); - When I call the startActivity(i) the error is shown (see below) my code is Intent i=new Intent(getApplicationContext(),NewRecipe.class); 使用getApplicationContext()时出错 - error when used getApplicationContext() 何时准确分配getApplicationContext? - When exactly getApplicationContext will be assigned? 无法在线程内调用getApplicationContext() - Can not call getApplicationContext() inside a thread 使用Toast时getApplicationContext()出错 - Error on getApplicationContext() when use Toast 使用时getApplicationContext()引发异常 - getApplicationContext() throws an exception when used
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM