The Major Types of Context

Context is an interface, so in theory anything could be a Context. However, there are only a few Context implementations that actually “do the heavy lifting” required of a fully-working Context.

Context from Components

Primarily, your components will give you a Context.

The one component that we have worked with so far is Activity. An Activity is itself a Context, which is why we can call getString() on it.

There are three other types of components:

The vast majority of the time, using a Context that you get from a “nearby” component is the right answer. For example, for code that is in an Activity, most of the time you will want to use the Activity itself as your Context.

Application

There is one other “root” Context besides your components: Application.

Each Android app process has an Application singleton. This object is created when the process is created, and it lives through the life of that process. In your regular app code, you get access to this singleton… by calling getApplicationContext() on some other Context.

As a result, Application may seem somewhat pointless. If you already have a Context, why would you need getApplicationContext() to get a different Context?

The answer lies in lifespan. Other types of Context — particularly an Activity — have short lifespans. As we will see later in the book, an Activity will come and go from the screen, even in some cases where the user might not think that there has been any change. Sometimes, we will need a Context that lives longer than this, and for that, we have Application.

That being said, only use Application when you have a clear reason why you need it.

Instrumented Tests

Note that in testing we get a Context in other ways.

For example, back in the chapter introducing testing, we had an ExampleInstrumentedTest class, both in Kotlin:

package com.commonsware.jetpack.hello

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
 * Instrumented test, which will execute on an Android device.
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
  @Test
  fun useAppContext() {
    // Context of the app under test.
    val appContext = InstrumentationRegistry.getInstrumentation().targetContext
    assertEquals("com.commonsware.jetpack.hello", appContext.packageName)
  }
}

…and in Java:

package com.commonsware.jetpack.hello;

import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Instrumented test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
  @Test
  public void useAppContext() {
    // Context of the app under test.
    Context appContext =
      InstrumentationRegistry.getInstrumentation().getTargetContext();
    assertEquals("com.commonsware.jetpack.hello", appContext.getPackageName());
  }
}

InstrumentationRegistry.getTargetContext() returns a Context from the app that we are testing.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.