Is there a way to get the current Context instance inside a static method? I'm looking for that way because I hate saving the 'Context' instance each time it changes.
75.3k 21 21 gold badges 174 174 silver badges 222 222 bronze badges asked Jan 4, 2010 at 21:15 Andrea Baccega Andrea Baccega 27.5k 13 13 gold badges 46 46 silver badges 48 48 bronze badgesNot saving Context is a good idea not just because it is inconvenient, but more because it can lead to huge memory leaks!
Commented Apr 30, 2012 at 5:35@VikramBodicherla Yes, but the answers below assume that we are talking about the application context. So, memory leaks are not an issue, but the user should only use these solutions where that is the correct context to use.
Commented Mar 31, 2013 at 17:58If you have to use a static way of getting Context , then there might be a better way to design the code.
Commented Feb 20, 2015 at 11:48Android documentation recommends passing the context to getters of singletons. developer.android.com/reference/android/app/Application.html
Commented Jul 14, 2015 at 8:10For preferring singletons and context passed with getInstance() over static context, please have a look, I tried to explain my reasoning here supported with working code: stackoverflow.com/a/38967293/4469112
Commented Feb 28, 2017 at 7:22In the Android Manifest file, declare the following.
Then write the class:
public class MyApplication extends Application < private static Context context; public void onCreate() < super.onCreate(); MyApplication.context = getApplicationContext(); >public static Context getAppContext() < return MyApplication.context; >>
Now everywhere call MyApplication.getAppContext() to get your application context statically.
31.6k 22 22 gold badges 109 109 silver badges 132 132 bronze badges answered Feb 25, 2011 at 6:37 Rohit Ghatol Rohit Ghatol 14.4k 1 1 gold badge 16 16 silver badges 2 2 bronze badges Is there any downside to this method? This seems like cheating. (A hack?) Commented Jul 7, 2011 at 2:32 Also maybe.. should we declare this static context variable as volatile ? Commented Mar 31, 2012 at 15:57@Tom This is not a case of a static data member being initially statically. In the given code, the static member is being initialized non-statically in onCreate(). Even statically initialized data is not good enough in this case because nothing insures that the static initialization of the given class will happen before it will be accessed during the static initialization of some other class.
Commented Mar 31, 2013 at 23:26@MelindaGreen According to the documentation for Application, onCreate() is called before any activity, service or receiver (excluding content providers) have been created. So wouldn't this solution be safe as long as you're not trying to access getAppContext() from a content provider?
Commented Feb 10, 2014 at 17:01In the modern spirit of "things that should be easy should be easy", there should really be a Context.getApplicationContext() or Application.getApplicationContext() static method. This object is a singleton and should be accessible as such without jumping through hoops. Until that is addressed, outside of a static initializer or a content provider, i.e. in 99% of my code, this answer provides a reasonable workaround. Thanks to the commenters who pointed out those specific cases where this technique is not safe.
Commented Jul 6, 2018 at 2:55The majority of apps that want a convenient method to get the application context create their own class which extends android.app.Application .
GUIDE
You can accomplish this by first creating a class in your project like the following:
import android.app.Application; import android.content.Context; public class App extends Application < private static Application sApplication; public static Application getApplication() < return sApplication; >public static Context getContext() < return getApplication().getApplicationContext(); >@Override public void onCreate() < super.onCreate(); sApplication = this; >>
Then, in your AndroidManifest you should specify the name of your class in the AndroidManifest.xml’s tag:
You can then retrieve the application context in any static method using the following:
public static void someMethod()
WARNING
Before adding something like the above to your project you should consider what the documentation says:
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.
REFLECTION
There is also another way to get the application context using reflection. Reflection is often looked down upon in Android and I personally think this should not be used in production.
To retrieve the application context we must invoke a method on a hidden class (ActivityThread) which has been available since API 1:
public static Application getApplicationUsingReflection() throws Exception
There is one more hidden class (AppGlobals) which provides a way to get the application context in a static way. It gets the context using ActivityThread so there really is no difference between the following method and the one posted above:
public static Application getApplicationUsingReflection() throws Exceptionanswered Jan 19, 2015 at 9:09 Jared Rummler Jared Rummler 38k 20 20 gold badges 135 135 silver badges 148 148 bronze badges
Yep! Love the last approach! Especially because I've internal/hidden APIs showing on Android Studio, so I don't even need to use Reflection, which seems safer (if the methods disappear, Android Studio will warn about it). Wonder why this is not on the SDK. Makes life easier, I think.
Commented May 28, 2021 at 22:28I just found a problem with the last approach. Doesn't seem to always return the context. getApplicationContext() and getBaseContext() work, but when I call ActivityThread.currentApplication(), it returns null. I'm calling all 3 inside a Thread which is declared inside a Service as a constant. Might not be a reliable way of getting a Context instance. Though I don't think it happened many times since my other comment. I think this is the only time. It's happening on Android 4.0.3 on the emulator, but doesn't happen with OnePlus X on Lollipop 5.1 nor on BV9500 with Oreo 8.1.
Commented Jul 31, 2021 at 0:38Assuming we're talking about getting the Application Context, I implemented it as suggested by @Rohit Ghatol extending Application. What happened then, it's that there's no guarantee that the context retrieved in such a way will always be non-null. At the time you need it, it's usually because you want to initialize an helper, or get a resource, that you cannot delay in time; handling the null case will not help you. So I understood I was basically fighting against the Android architecture, as stated in the docs
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.
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. :)
She is also suggesting the solution to this problem:
If what you want is some global state that can be shared across different parts of your app, use a singleton. [. ] And this leads more naturally to how you should be managing these things -- initializing them on demand.
so what I did was getting rid of extending Application, and pass the context directly to the singleton helper's getInstance(), while saving a reference to the application context in the private constructor:
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; > >
the caller will then pass a local context to the helper:
Helper.getInstance(myCtx).doSomething();
So, to answer this question properly: there are ways to access the Application Context statically, but they all should be discouraged, and you should prefer passing a local context to the singleton's getInstance().
For anyone interested, you can read a more detailed version at fwd blog