Is it safe to save the app context to a static variable in Android?

AndroidProcessStaticAndroid Context

Android Problem Overview


I know that usage of static variables on Android is quite risky, especially if you reference them to activities. However, if I have a class that extends Application (let's call this class "App"), is it safe to reference to the instance of this class?

If so, is it also safe for any other class to have any kind of reference to the application context? I mean, can there be a memory leak if I have a reference to the application context in any kind of class?

The purpose is that no matter in which scope I am in, I can always get a reference to the application context. I think it's safe, since if the system closes the application, the static variable is also gone till the next time the application starts again, which will initialize the static variable again.

Also, not that it matters much, but if I use multiple processes, will I get totally different references to App class on each process?

As an example of code, here's what I'm thinking about:

public class App extends Application
{
    private static Context _appContext;

    @Override
    public void onCreate()
    {
        super.onCreate();
        _appContext = this;
    }

    public static Context getAppContext()
    {
        return _appContext;
    }
}

Android Solutions


Solution 1 - Android

> is it safe to save the app context to a static variable?

Presently, yes, it appears to be safe, though I would not have getAppContext() return Context, but instead return App or Application.

That being said, the fact that the core Android team did not set it up this way in the first place suggests that perhaps there may be hidden issues of which we are unaware, or that in the future this approach may introduce problems.

As the acronym of the saying goes, YMMV. :-)


EDIT

> if so , is it also safe for any other class to have any kind of reference to the application context ?

I have no idea what you mean by "safe" here.

> but if i use multiple processes , i will get totally different references to App class on each process , right?

If you use multiple processes, you should be slapped with a trout. But, yes, you should get distinct App instances per process.

Solution 2 - Android

It should be safe. Also the following note from the API docs could be relevant to you:

> There is normally no need to subclass Application. In most situation, > 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), the function to retrieve it can be given a > Context which internally uses Context.getApplicationContext() when > first constructing the singleton.

Solution 3 - Android

It's safe to do this in Application#onCreate() because the Application is created before any activity. If your app gets killed in the background, the Application instance will be recreated and your global will be set before any activity runs.

It's important to note that you should never set global variables from an activity. If you do, your app could fail in the following way:

  1. Set global in activity A
  2. Navigate to activity B
  3. App goes into background
  4. Framework kills app and process
  5. App is restored
  6. Framework creates activity B. Activities in the backstack are not created until you navigate back to them, so the global is not set!
  7. Activity B attempts to use global, and boom... NullPointerException

Solution 4 - Android

Interesting comment popped up from Studio when I was tidying up nasty static contexts:

"This is a leak (and also breaks Instant Run)."

So with the launch of Instant Run, we have the case where Android developers are not planning on saving static variables. Whilst instant run is not (yet) on my agenda, it is useful to know that there is a specific example where it is not only bad practice, but the use case where it is wrong is identified.

Solution 5 - Android

This is the warning when you create a Context context; in android-studio :

> Do not place Android context classes in static fields; this is a > memory leak and also breaks Instant Run. > > A static field will leak contexts. > > Non-static inner classes have an implicit reference to their outer > class. > > If that outer class is for example a Fragment or Activity, then this > reference means that the long-running handler/loader/task will hold a > reference to the activity which prevents it from getting garbage > collected. Similarly, direct field references to activities and > fragments from these longer running instances can cause leaks. > > ViewModel classes should never point to Views or non-application > Contexts.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionandroid developerView Question on Stackoverflow
Solution 1 - AndroidCommonsWareView Answer on Stackoverflow
Solution 2 - AndroidDheeraj VepakommaView Answer on Stackoverflow
Solution 3 - AndroidKevin KrumwiedeView Answer on Stackoverflow
Solution 4 - AndroidIan SpencerView Answer on Stackoverflow
Solution 5 - AndroidAli KhakiView Answer on Stackoverflow