[英]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])
. Activity
和Application
都有方法attach(Context [...other stuff])
。 Each of them calls attachBaseContext()
with the passed-in Context
. 它们中的每一个都使用传入的
Context
调用attachBaseContext()
。
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
。 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
。 LoadedApk
class, you'll find makeApplication
which creates a ContextImpl
that gets passed to an Application
. LoadedApk
类中,您将找到makeApplication
,它创建一个传递给Application
的ContextImpl
。 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.