«

Android Context on demand

For our Android application, we initially had the need, like many of you, to retrieve the context statically. We looked it up over Stack Overflow, where the most voted answer (at the moment of writing) suggests to extend MainApplication, a trick I’m sure some of you have done already. So did we. Everything worked fine, until one day we noticed a crash.

Let’s first of all have a look at the crash stack trace:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at com.comptel.smpl.package.SomeClass.<clinit>(SourceFile:58)

Whereas in our SomeClass we had such code:

mSharedPref= MainApplication.getAppContext().getSharedPreferences(MainApplication.getAppContext().getPackageName() + "someString", Context.MODE_PRIVATE);

The case was clear from the very beginning: trying to get the package name from the static application context, we were given a null reference, therefore the JNE. Our MainApplication was extending Application as suggested in Stack Overflow:

public class MainApplication extends Application {

    private static Context context;

    public void onCreate() {
        super.onCreate();
        MainApplication.context = getApplicationContext();
    }

    public static Context getAppContext() {
        return MainApplication.context;
    }
}

We extended Application, getting and saving a reference of the application context upon creation, which then we were passing around in a static way. This approach works most of the times because Application is documented as a

Base class for maintaining global application state. […] The Application class, or your subclass of the Application class, is instantiated before any other class when the process for your application/package is created.

The real problem is, when such a crash happens, you can’t just handle the null retrieved context, because most likely you’ll need it to initialize some resources, in a class which doesn’t really have any choice of being initialized later on.


Wounds can create monsters and you are wounded, martial. And wouldn’t you agree, when you see a monster, you must stop it?


So I had a deeper look into the real issue, and once fixed I also replied on Stack Overflow; but I would like here to extend my answer, give to it the proper context (pun intended), and also suggest a better, more appropriate way to deal with this issue, in the hope that you could benefit from my finding.

The first hint came from Application documentation itself, whereas it states

Note: There is normally no need to subclass Application. In most situations, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), include Context.getApplicationContext() as a Context argument when invoking your singleton’s getInstance() method.

As it’s a lot to digest, I didn’t initially got what it exactly meant, so I kept on googling, until I ended up reading this thread where Dianne Hackborn herself explains what the issue is

The only reason Application exists as something you can derive from is because during the pre-1.0 development one of our application developers was continually bugging me about needing to have a top-level application object they can derive from so they could have a more “normal” to them application model, and I eventually gave in. I will forever regret giving in on that one. :)

and she’s also so generous to give me the solution

If what you want is some global state that can be shared across different parts of your app, use a singleton. The singleton won’t get GCed, because you have a global static reference on it. And this leads more naturally to how you should be managing these things – initializing them on demand.

so I finally understood I was fighting with the system, and the solution was to get the application context on demand. I truly think this is, in Android, the proper approach to handle the context, and if any of your code has the need for retrieving the context statically, you should change it to be retrieved on demand instead.


I’ve built something valuable here and valuable things have a way of being misunderstood in their own time. Everyone wants a quick fix. I’m trying to do something that people, yourself included, don’t understand, and I’m not going to give up without a fight


So let’s have a look at the code.

I’ll show you an example with a singleton, where you want or need a global state to share with different modules of your app, and you want to pass the context on demand to your singleton.

Let’s start with a basic simple singleton:

public class MyHelper {
    private static MyHelper instance;

    private MyHelper() {
        // ...
    }

    public static MyHelper getInstance() {
        synchronized(MyHelper.class) {
            if (instance == null) {
                instance = new MyHelper();
            }
            return instance;
        }
    }

    public void doSomething() {
        // here I need to do something which requires the context
    }
}

If you’re not familiar with this pattern or how to implement it, there’s a lot of documentation online. If you focus on doSomething(), you’ll need to access the context, for instance to read the package name or some resources; usually you’ll retrieve a static reference of the context in the constructor, just to use it later on when doSomething() is called. But instead the correct approach is to pass the context on demand:

public class MyHelper {
    private static MyHelper instance;
    private final Context mContext;

    private MyHelper(@NonNull Context context) {
        mContext = context.getApplicationContext();
        // ...
    }

    public static MyHelper getInstance(@NonNull Context context) {
        synchronized(MyHelper.class) {
            if (instance == null) {
                instance = new MyHelper(context);
            }
            return instance;
        }
    }

    public void doSomething() {
        // here I need to do something which requires the context
        mContext.getPackageName();
    }
}

As you can see, the main difference is how the context is passed: on demand. When our little helper is used, the callers will call something like:

public class SomeActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ..

        // here I need to access some method of my helper
        MyHelper.getInstance(this).doSomething();
    }
}

public class SomeOtherActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ..

        // here I need to access some method of my helper
        MyHelper.getInstance(this).doSomethingElse();
    }
}

At runtime, many different parts of your code will need, at any time, to access MyHelper to utilise any of its methods, so in our example whichever of the two activities is created first, it will initialize the singleton helper on demand, because getInstance() will enforce a valid context to be passed every single time, from which the application context will be referenced in the helper constructor, only if not initialized already. It’s important not to keep a reference of the context itself (that will cause a memory leak, and since Studio 2.3.1 you’ll see a warning), but of the application context instead, because it is

the context of the single, global Application object of the current process

so the application context is global (perfect for our singleton) and related to our process; our singleton lifecycle starts with its lazy initialization and terminates only once our process is exited or killed. Such a singleton helper has a lifecycle which is separated from any other local current context, for instance the one represented by any activity, which are created and destroyed at use. Of course the assumption here is that you have a need for such an helper, which is needed at any time, from different parts of your app, to provide access to some global information.


No one’ll talk, its like they’re scared of something


I know some people consider singleton an antipattern, but I truly think it is not per se; it depends on how singletons are designed and used. Still quoting Dianne Hackborn:

The framework itself has tons and tons of singletons for all the little shared data it maintains for the app, such as caches of loaded resources, pools of objects, etc. It works great.

so you should consider carefully to use a singleton, but for caches, pools, and similar is a valid appropriate pattern and fits the purpose.

In case you are planning to access such a singleton in a multithread environment, the double-check locking can be used:

public class MyHelper {
    private static volatile MyHelper instance;
    private final Context mContext;

    private MyHelper(@NonNull Context context) {
        mContext = context.getApplicationContext();
        // ...
    }

    public static MyHelper getInstance(@NonNull Context context) {
        MyHelper localInstance = instance;
        if (localInstance == null) {
            synchronized(MyHelper.class) {
                localInstance = instance;
                if (localInstance == null) {
                    instance = localInstance = new MyHelper(context);
                }
           }
        }
        return localInstance;
    }

    public void doSomething() {
        // here I need to do something which requires the context
        mContext.getPackageName();
    }
}

All quotes from Shutter Island © 2010 Martin Scorsese. All rights reserved.