I have looked into Android sources just out of interest. What I found is that Context
is an abstract class with abstract method:
public abstract Co
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. There's this implementation, and the one in 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
doesn't care which kind it is; it just knows that they have a method getApplicationContext
and it wants to call that method when asked. (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.)
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.
Both Activity
and Application
have methods attach(Context [...other stuff])
. Each of them calls attachBaseContext()
with the passed-in Context
.
Instrumentation
class, you'll find android.app.Instrumentation.newApplication(), where a ContextImpl
is created, and passed into an Application
. ActivityThread
class, you'll find handleBindApplication which creates a ContextImpl
that gets passed to the Activity
as its root Context
.LoadedApk
class, you'll find makeApplication
which creates a ContextImpl
that gets passed to an Application
. Here are the places it's called.So, at the end of the day, mBase
typically ends up as a ContextImpl
.
Potentially useful links I looked at while finding all of this out: