Context of “Context” in Android

Abhilash Das
7 min readSep 26, 2019

The most used and underrated thing in android development is Context . You use it to start an activity, start a service, get some string or asset resource. Still, we ignore the importance of Context and what it really means.

In this article, I’ll try to give you a glimpse of what is context actually is.

As usual, we start with the official doc and then go deeper to understand the meaning of it.

Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

Once this official jargon set aside, let’s understand what it really is.

Definition of Context

  • Context represents environment data
  • It provides access to things such as databases

Simpler terms (example 1)

  • It’s like access of android activity to the app’s resource.
  • It’s similar to when you visit a hotel, you want breakfast, lunch & dinner in the suitable timings, right?
  • There are many other things you like during the time of stay. How do you get these things? You ask the room-service person to bring these things for you.
  • Here the room-service person is the context considering you are the single activity and the hotel to be your app, finally, the breakfast, lunch & dinner have to be the resources.

Simpler terms (example 2)

Consider context as remote of a TV & channel’s in the television are resources, services, using intents, etc. Here remote acts as an access to get access to all the different resources into the foreground.

  • So, Remote has access to channels such as resources, services, using intents, etc.
  • Likewise … Whoever has access to remote naturally has access to all the things such as resources, services, using intents, etc

Simpler terms (example 3)

Every boss has an assistant to look after, to do all less important and time-consuming tasks. If a file or a cup of coffee is needed, an assistant is on the run. Some bosses barely know what’s going on in the office, so they ask their assistants regarding this too. They do some work themselves but for most other things they need the help of their assistants.

In this scenario,

Boss — is the Android application

Assistant — is context

Files/Cup of coffee — are resources

Context is the base class for Activity, Service, Application, etc

The Context class itself is declared as an abstract class, whose implementation is provided by the Android OS.

You can understand very well, now, why the name is Context. It’s because it’s just that. The Context provides the link or hook, if you will, for an Activity, Service, or any other component, thereby linking it to the system, enabling access to the global application environment. In other words: the Context provides the answer to the components question of “where the hell am I in relation to app generally and how do I access/communicate with the rest of the app?” Let’s have a quick look at the methods exposed by the Context class provides some further clues about its true nature.

Here’s a random sampling of those methods:

  1. getAssets()
  2. getResources()
  3. getPackageManager()
  4. getString()
  5. getSharedPrefsFile()

What do all these methods have in common? They all enable whoever has access to the Context to be able to access application-wide resources.

Context, in other words, hooks the component that has a reference to it to the rest of the application environment. The assets ( /assets folder in your project), for example, are available across the application, provided that an Activity, Service or whatever knows how to access those resources. Same goes for getResources() which allows doing things like getResources().getColor() which will hook you into the colors.xml resource (nevermind that aapt enables access to resources via java code, that’s a separate issue).

The upshot is that Context is what enables access to system resources and its what hook components into the “greater app".

Let’s look at the subclasses of Context, the classes that provide the implementation of the abstract Context class. The most obvious class is the Activity class. Activity inherits from ContextThemeWrapper, which inherits from ContextWrapper, which inherits from Context itself. Those classes are useful to look at to understand things at a deeper level, but for now, it’s sufficient to know that ContextThemeWrapper and ContextWrapper are pretty much what they sound like. They implement the abstract elements of the Context class itself by “wrapping” a context (the actual context) and delegating those functions to that context. An example is helpful - in the ContextWrapper class, the abstract method getAssets from the Context class is implemented as follows:

@Override
public AssetManager getAssets() {
return mBase.getAssets();
}

mBase is simply a field set by the constructor to a specific context. So a context is wrapped and the ContextWrapper delegates its implementation of the getAssets() method to that context. Let’s get back to examining the Activity class which ultimately inherits from Context to see how this all works.

You probably know what an Activity is, but to review — it’s basically ‘a single thing the user can do. It takes care of providing a window in which to place the UI that the user interacts with. Developers familiar with other APIs and even non-developers might think of it vernacularly as a “screen.” That’s technically inaccurate, but it doesn’t matter for our purposes. So how do Activity and Context interact and what exactly is going in their inheritance relationship?

Again, it’s helpful to look at specific examples. We all know how to launch Activities. Provided you have “the context” from which you are starting the Activity, you simply call startActivity(intent), where the Intent describes the context from which you are starting an Activity and the Activity you’d like to start. This is the familiar startActivity(this, SomeOtherActivity.class).

And what is this? this is your Activity because the Activity class inherits from Context. The full scoop is like this: When you call startActivity, ultimately the Activity class executes something like this:

Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);

So it utilizes the execStartActivity from the Instrumentation class (actually from an inner class in Instrumentation called ActivityResult).

At this point, we are beginning to get a peek at the system internals.

This is where OS actually handles everything. So how does Instrumentation start the Activity exactly? Well, the param this in the execStartActivity method above is your Activity, i.e. the Context, and the execStartActivity makes use of this context.

A 30,000 overview is this: the Instrumentation class keeps tracks of a list of Activities that it’s monitoring in order to do its work. This list is used to coordinate all of the activities and make sure everything runs smoothly in managing the flow of activities.

There are some operations which I haven’t fully looked into which coordinate thread and process issues. Ultimately, the ActivityResult uses a native operation - ActivityManagerNative.getDefault().startActivity() which uses the Context that you passed in when you called startActivity. The context you passed in is used to assist in “intent resolution” if needed. Intent resolution is the process by which the system can determine the target of the intent if it is not supplied.

And in order for Android to do this, it needs access to information that is supplied by Context. Specifically, the system needs to access to a ContentResolver so it can “determine the MIME type of the intent’s data". This whole bit about how startActivity makes use of context was a bit complicated and I don’t fully understand the internals myself. My main point was just to illustrate how application-wide resources need to be accessed in order to perform many of the operations that are essential to an app. Context is what provides access to these resources. A simpler example might be Views. We all know what you create a custom View by extending RelativeLayout or some other View class, you must provide a constructor that takes a Context as an argument. When you instantiate your custom View you pass in the context. Why? Because the View needs to be able to have access to themes, resources, and other View configuration details. View configuration is actually a great example. Each Context has various parameters (fields in Context’s implementations) that are set by the OS itself for things like the dimension or density of the display. It’s easy to see why this information is important for setting up Views, etc.

One final word: For some reason, people new to Android (and even people not so new) seem to completely forget about object-oriented programming when it comes to Android. For some reason, people try to bend their Android development to pre-conceived paradigms or learned behaviors.

Android has it’s own paradigm and a certain pattern that is actually quite consistent if let go of your preconceived notions and simply read the documentation and dev guide. My real point, however, while “getting the right context” can sometimes be tricky, people unjustifiably panic because they run into a situation where they need the context and think they don’t have it. Once again, Java is an object-oriented language with an inheritance design.

You only “have” the context inside of your Activity because your activity itself inherits from Context. There’s no magic to it (except for the all the stuff the OS does by itself to set various parameters and to correctly “configure” your context). So, putting memory/performance issues aside (e.g. holding references to context when you don’t need to or doing it in a way that has negative consequences on memory, etc), Context is an object like any other and it can be passed around just like any POJO (Plain Old Java Object). Sometimes you might need to do clever things to retrieve that context, but any regular Java class that extends from nothing other than Object itself can be written in a way that has access to context; simply expose a public method that takes a context and then uses it in that class as needed. This was not intended as an exhaustive treatment on Context or Android internals, but I hope it’s helpful in demystifying Context a little bit.

--

--