Static way to get 'Context' in Android?

786,479

Solution 1

Do this:

In the Android Manifest file, declare the following.

<application android:name="com.xyz.MyApplication">

</application>

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.

Solution 2

The 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:

<application 
    ...
    android:name="com.example.App" >
    ...
</application>

You can then retrieve the application context in any static method using the following:

public static void someMethod() {
    Context context = App.getContext();
}

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 {
    return (Application) Class.forName("android.app.ActivityThread")
            .getMethod("currentApplication").invoke(null, (Object[]) null);
}

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 Exception {
    return (Application) Class.forName("android.app.AppGlobals")
            .getMethod("getInitialApplication").invoke(null, (Object[]) null);
} 

Happy coding!

Solution 3

Assuming 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.

and explained by Dianne Hackborn

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

Solution 4

No, I don't think there is. Unfortunately, you're stuck calling getApplicationContext() from Activity or one of the other subclasses of Context. Also, this question is somewhat related.

Solution 5

Here is an undocumented way to get an Application (which is a Context) from anywhere in the UI thread. It relies on the hidden static method ActivityThread.currentApplication(). It should work at least on Android 4.x.

try {
    final Class<?> activityThreadClass =
            Class.forName("android.app.ActivityThread");
    final Method method = activityThreadClass.getMethod("currentApplication");
    return (Application) method.invoke(null, (Object[]) null);
} catch (final ClassNotFoundException e) {
    // handle exception
} catch (final NoSuchMethodException e) {
    // handle exception
} catch (final IllegalArgumentException e) {
    // handle exception
} catch (final IllegalAccessException e) {
    // handle exception
} catch (final InvocationTargetException e) {
    // handle exception
}

Note that it is possible for this method to return null, e.g. when you call the method outside of the UI thread, or the application is not bound to the thread.

It is still better to use @RohitGhatol's solution if you can change the Application code.

Share:
786,479
Andrea Baccega
Author by

Andrea Baccega

Updated on March 01, 2022

Comments

  • Andrea Baccega
    Andrea Baccega over 2 years

    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.

    • Vikram Bodicherla
      Vikram Bodicherla about 12 years
      Not saving Context is a good idea not just because it is inconvenient, but more because it can lead to huge memory leaks!
    • Tom
      Tom over 11 years
      @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.
    • Anonsage
      Anonsage over 9 years
      If you have to use a static way of getting Context, then there might be a better way to design the code.
    • Marco Luglio
      Marco Luglio almost 9 years
      Android documentation recommends passing the context to getters of singletons. developer.android.com/reference/android/app/Application.html
    • Alessio
      Alessio over 7 years
      For 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
    • tricknology
      tricknology about 7 years
      If you're looking at needing static context you should consider that maybe you have a design problem. Check Factory design patterns and like @VikramBodicherla said, huge memory leaks!
    • DADi590
      DADi590 over 3 years
      @Tom What other types of context would be a problem here? Seems the Application context is not a problem. What types are then?
    • Martin Zeitler
      Martin Zeitler over 3 years
      Context and ApplicationContext are the same, but one of them is themed. Whenever static code requires Context, better ignore these so called "solutions" and ask yourself how to properly pass it.
  • jjnguy
    jjnguy almost 13 years
    Is there any downside to this method? This seems like cheating. (A hack?)
  • Nate
    Nate almost 13 years
    That's right. If you use the application context for that, you may see your dialog hidden under foreground activities.
  • Melinda Green
    Melinda Green over 12 years
    The downside is that there is no guarantee that the non-static onCreate() will have been called before some static initialization code tries to fetch your Context object. That means your calling code will need to be ready to deal with null values which sort of defeats the whole point of this question.
  • Vladimir Sorokin
    Vladimir Sorokin over 12 years
    Also maybe.. should we declare this static context variable as volatile?
  • Tal Weiss
    Tal Weiss almost 12 years
    The right link to the article: android-developers.blogspot.co.il/2009/01/…
  • RaphMclee
    RaphMclee almost 12 years
    @VladimirSorokin: no volatile keyword is needed as the context referes always to the same object. The value of the pointer could be made final as it never changes once assigned.
  • Vladimir Sorokin
    Vladimir Sorokin almost 12 years
    @RaphMclee: You can not make it final because it's initialized not in c-tor. Still the context variable may be accessed by multiple threads. And according to "Java Concurrency In Practice - 3.5.3. Safe Publication Idioms": to publish a reference safly you should use one of the following approaches: static initializer, volatile field, AtomicReference, final field, lock. Otherwise you might have problems with concurrency. But I'm not 100% sure about our particular case, there are different subtle nuances, so I decided to use volatile just in case, it doesn't affect performance anyway.
  • Kiirani
    Kiirani over 11 years
    Does anybody know the reasoning for setting the context variable in onCreate() instead of in a constructor?
  • AndroidGuy
    AndroidGuy over 11 years
    I used the above method KennyTM, but sometimes the method returns null. Is there some other alternative to this ? Like if we get a null here, we can retrieve the context from elsewhere. In my case, onCreate() of Application is not called. But the above method gets called before it. Plzzz help
  • GorillaApe
    GorillaApe over 11 years
    @Kiirani probably because it doesnt exist before ? You might get nullo.
  • Tom
    Tom over 11 years
    @MelindaGreen I disagree. Where you have static attributes that are initialized with a static, then you already know that you are doing something that depends on order of initialization and need to be careful. Mostly, you just won't use this in that way.
  • Tom
    Tom over 11 years
    @nerith Create a 'surrogate' class in your common library code and then set Surrogate.context from App.onCreate(). I also do this for BuildConfig.DEBUG flag since it is not accessible from library code.
  • Melinda Green
    Melinda Green about 11 years
    @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.
  • Tom
    Tom about 11 years
    @MelindaGreen I agree with the statement you just made. For the reason you stated I simply would not reference getApplicationContext in a static initializer. The OP wants a way to access the context via a static method, but I do not interpret that to mean that he wants to be able to use that static method in a static initializer.
  • Melinda Green
    Melinda Green about 11 years
    @Tom Again, this not about static initialization but initialization order in general. The proposed solution simply sets up a race condition. If it generally seems to work, that just seems like good luck (I.E bad luck). And that's the downside that I described in my first comment which is that to be safe, callers would need to be ready to get null values. Unfortunately, that seems like the problem the OP was trying to solve. Depending upon the situation, perhaps the OP didn't realize that Activities and Services are Contexts and might have had no problem to begin with.
  • Richard J. Ross III
    Richard J. Ross III about 11 years
    This only works if you are inside an inner class, which is hardly the case in the OP.
  • handtwerk
    handtwerk about 11 years
    This would work as long as the ANY_METHOD is called after MainActivity is created, but keeping static references to activities almost inevitably introduces memory leaks (as other responses to OP's question already mention), so if you really must keep a static reference, use the application context only.
  • Darius
    Darius over 10 years
    Apparently this just got downvoted.. an explanation would be nice!?
  • Reinherd
    Reinherd over 10 years
    Inner classes are evil. Worst part is that a lot of people do that for AsyncTasks and things like that, because many tutorials do it that way...
  • Magnus
    Magnus over 10 years
    @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?
  • hopia
    hopia over 10 years
    @BadCash I think in a way, it is "safe", because the framework guarantees onCreate will get called for each Activity, and by that time, the application context will also already be created. However, from a maintenance point-of-view, there are a few caveats you have to be aware of, and that is, you have to be prepared to get null values depending on where you call this function from. (ie. if you call it from a constructor, the context static variable may not have been initialized yet.) So, you should always check for null, just to be sure. Personally, I would not do it this way.
  • Melinda Green
    Melinda Green over 10 years
    @BadCash, thanks for pointing out the documentation. It says up front that there's generally no need to subclass from Application because singletons are probably better. It then says that to implement such a singleton, your function to get the instance should pass in its Context on which your singleton initialization calls getApplicationContext(). That way the first call will cause the singleton to be set and callers won't have to worry about getting nulls. Unfortunately that means that they have to have a Context, which was the original problem. Erich's answer below is the correct one.
  • Ernani Joppert
    Ernani Joppert almost 10 years
    I didn't downvote this, but Javascript has nothing to do with the question at hand, that would explain any downvotes you may have had! Cheers.
  • Darius
    Darius almost 10 years
    That would be pretty nonsensical given it's inspired by some aspects of jQuery like a fluent interface, and its abstractions.. those are principles agnostic of the underlying language!
  • Ernani Joppert
    Ernani Joppert almost 10 years
    I get your idea and your explanation, it has context, but, go figure what other users think. In any case, I am with you!
  • Govind
    Govind almost 10 years
    +1 first of all. And the possible error that comes is Unable to start activity ComponentInfo{com.samples/com.MyActivity}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
  • Rouz
    Rouz over 9 years
    Will onCreate method be called when app is invoked with android.intent.action.BOOT_COMPLETED broadcast? it seems that was the root of my problems. I was expecting that onCreate to be invoked but for some reason that does not seem to be the case. When using solution of yours one should be careful in some cases.
  • AlexVPerl
    AlexVPerl about 9 years
    This will not always work in the case where GC cleaned out all activity related stuff.
  • MinceMan
    MinceMan about 9 years
    If all you need is context you can call activity.getApplicationContext(); That can be held onto statically without having to worry about leaks.
  • npace
    npace almost 9 years
    @TeeTracker In this case, there won't be a leak because the Application object is alive for as long as the app itself is alive, i.e. it doesn't get garbage collected during the lifetime of the app.
  • Jerry Brady
    Jerry Brady almost 9 years
    There are clear cases when an application has a content provider in which the content provider is initialized before the application object and therefore you cannot count on the static field to be initialized in this case.
  • Darius
    Darius over 8 years
    So you're downvoting it because it was inspired by the API semantics of a framework that isn't on the same platform?! I think you guys miss the point of applying platform-agnostic principles.....................................
  • Ajax
    Ajax almost 8 years
    So long as you aren't initializing classes that will statically try to reference the statically stored context, doing this in a subclass of Application (which is defined as THE application in AndroidManifest.xml, is safe, because the Android system guarantees that your application instance .onCreate will be the very first thing called before anything else. So, while not a "safe" way to do this in normal java, this would be like setting a static field in a regular java main... Safe, so long as you aren't doing god-awful static things with other static initialized fields.
  • Versa
    Versa almost 8 years
    It's not like the class/method names are set in stone, kept it long and (hopefully) descriptive for a Q&A, shortened it for my own use.
  • BlueWizard
    BlueWizard over 7 years
    this will produce memory leaks
  • BlueWizard
    BlueWizard over 7 years
    this answer is totally unrelated to JavaScript. Read the answer before you downvote :/
  • jk7
    jk7 over 7 years
    This is interesting. Good to learn about ContextWrapper. However, if you need to pass in the application context to this constructor, you still need to get it from somewhere.
  • Gero
    Gero about 7 years
    Note that in Android Studio (2.3.1, at least) you a warning to not save the context in a static field when you do this (memory leak). Is that actually correct in this case? I got rid of it by getting everything I needed from the context and save that (file paths and so on) in members, so I am fine, just clarifying. Also this approach seems a bit weird at first because you don't do anything with the context on subsequent calls of getInstance(). :) Still, the answer convinced me more than the accepted one.
  • Alessio
    Alessio about 7 years
    @Gero I save the application context reference because I assume some other method of MyHelper will need it. If you don't need it ever, then you shouldn't keep a reference of it (for what for?). Also, your approach doesn't allow resource changes (for instance when user switch language), so I wouldn't recommend it. Last but not least, lint warning is correct because what lint see is a Context, but in this case I take the application context ("the context of the single, global Application object of the current process") on a singleton, which after lazy initialization is available until crash
  • Gero
    Gero about 7 years
    @Alessio Yup, in my case I don't accommodate for ressource changes, but that is fine for me, in my app's context. I also, in the end, did indeed remove a reference to the context (after realizing I can simply live with the data I got from it on initialization). So I meant to say "Thus, in my case it's a bit weird to keep on handing over the context on subsequent calls of getInstance()", sorry if that was unclear. Also, thanks for clarifying that it's fine to ignore the lint warning as long as you just save the application context. I already guessed so, but confirmation is always good.
  • Alessio
    Alessio about 7 years
    @Gero in your specific case then I'll be even more defensive: instead of passing the context to the constructor or getInstance(), just pass the needed initialization parameters directly, and let the caller to use the context to retrieve them. Then your interface / API is even more clear, because it indicates your class or helper doesn't need the context at all. You're welcome, I'm happy to clarify and also I'm planning to write down an extended entry for this answer, so I have more space to comment and answer any doubt.
  • Gero
    Gero about 7 years
    @Alessio Yes, that is probably more useful. I'm not yet done with the class anyway, so that's on my refactoring ToDo. I'm also considering to have a specific setupInstance() method or something for this and have the singelton use some meaningful default behavior if that hasn't been called yet. The downside of that would be that the lazy-initialization isn't very nice with this, as it isn't when you need to pass in useless parameters all the time (that were only used on the first call), whether it's wrapped in the context or individual ones. It's a bummer the instance can't get those by itself.
  • Gero
    Gero about 7 years
    @Alessio Great article! This is exactly what I finally did (apart from the multiple threading concept as I don't need that for now). Thanks a lot for going the extra mile and also compiling the various sources about the issue (like Dianne's statement).
  • Phillip Kigenyi
    Phillip Kigenyi almost 7 years
    @Alessio Doesn't this method lead to memory leaks
  • Alessio
    Alessio almost 7 years
    @codephillip no. Why do you think so? Please tell me more, also read my blog entry for more details on this
  • Phillip Kigenyi
    Phillip Kigenyi almost 7 years
    @Alessio its a singleton taking in the context from the component(activity). What happens when the component is killed by the system. What happens when onResume(), onStart() are called. You should test the app by opening several other applications on your phone then returning after like 5-10 minutes, you may find that your app has crashed because the singleton is referencing a context from a killed component(activity)
  • Alessio
    Alessio almost 7 years
    @codephillip I don't understand what you're talking about. The singleton references the application context retrieved from the passed activity, not the host activity. That's legit, and it will not cause any memory leak. That's the main point of the blog I wrote. If you really think you're right, please send me a sample code where I can reproduce the memory leak you're talking about, because that's not the case.
  • MahNas92
    MahNas92 over 6 years
    This solution triggers an Android Lint Performance warning, since Android Contexts placed in static fields constitutes a memory leak... You can check it out for yourself, in Android Studio: Analyze>Inspect Code...
  • Crearo Rotar
    Crearo Rotar about 6 years
    It's upsetting to see how many upvotes this answer has. You should never hold a static instance to context - for proofs sake, try using Leak Canary (github.com/square/leakcanary) and find the memory leak caused because of this. @people-with-enouhg-rep-and-Android-knowledge, please re-review this answer and act accordingly. This is guaranteed to be used by beginners and it's plain simple wrong.
  • Louis CAD
    Louis CAD about 6 years
    @cyrilchampier I made a library that works with libraries: github.com/LouisCAD/Splitties/blob/master/appctx/README.md It uses a dummy ContentProvider to get a safe Context
  • Ian Lovejoy
    Ian Lovejoy almost 6 years
    In 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.
  • user1506104
    user1506104 almost 6 years
    You are right. And it will also result to memory leaks!
  • Sarthak Mittal
    Sarthak Mittal almost 6 years
    @CrearoRotar It ain't wrong actually, storing static reference to application context is not at all a bad practice in my opinion, there won't be any memory leaks because the android system would already have killed your process, although I agree that it should be used with care.
  • Mark McKenna
    Mark McKenna almost 6 years
    I think @KigenyiPhillip is correct, and this does still represent a resource leak. Picture the reference chart after your first call to getInstance(ctx). You have a GC root instance of type MyHelper, which has a private field mContext of type Context, which references the application context collected via the context passed to getInstance(). instance is never set a second time, nor cleared, so GC will never catch the appcontext referenced by instance. You don't leak any activities so it's low cost IMO.
  • Alessio
    Alessio almost 6 years
    @MarkMcKenna as you state "which has a private field mContext of type Context, which references the application context", so that's clear to you that mContext is a reference to the application context, not to any context. In getApplicationContext() docs you read: "a Context whose lifecycle is separate from the current context, that is tied to the lifetime of the process rather than the current component". How can this create a memory leak? The application context is GC'd only when the process exits.
  • Mark McKenna
    Mark McKenna almost 6 years
    @Alessio if you accept that a reference to the application context doesn't qualify as a resource leak, then you can simplify this by posting a static reference to this in Application.onCreate(), which makes the accepted answer better.
  • Alessio
    Alessio almost 6 years
    @MarkMcKenna first you say it's a leak, now you're saying is not. A reference to the application context is not a leak. But the problem of the accepted answer (to extend Application and retrieve the context statically) is not in leaking resources, but retrieving a static context which could be 'null', and at that point you can't do much with it. I explained this in more details in our blog, please read it through carefully. After that, if you've any concern, let me know. Also read Dianne words very carefully, if not mine.
  • TheRealChx101
    TheRealChx101 over 4 years
    What exactly will it be leaking since the context in this case is bound to the application? If the application dies, so does everything else.
  • ToolmakerSteve
    ToolmakerSteve over 4 years
    @Alessio I've looked at your blog, but I don't understand one thing: you got a null when using the app-subclass technique, so you were running code before app onCreate: what Context did you have access to in such code, to pass to the helper? As an aside, Mark McKenna is partially correct: it makes no difference whether you use a separate singleton class, as you do, or whether this technique is used while subclassing Application - so you could have omitted all that discussion; the essence is that you start from some context, to avoid null. Good point re not caching the non-app context.
  • ToolmakerSteve
    ToolmakerSteve over 4 years
    @MelindaGreen - re "Unfortunately that means that they have to have a Context, which was the original problem." Yes and no. To avoid null, it is necessary to first run some code that has some Context - so there is no truly universal solution, as Erich says and you mention. OTOH, it might be possible to order one's code such that some Context exists "early enough". If so, then whatever Context that is, should call myContext.getApplicationContext, and store that into this static global. Do you know whether there is ever any context prior to Application.onCreate?
  • Melinda Green
    Melinda Green over 4 years
    @ToolmakerSteve, No, I don't know, but I suggest you don't count on it unless the documentation explicitly says you can.
  • Alessio
    Alessio over 4 years
    @ToolmakerSteve I don't understand your question, but basically what I experienced was that some statically loaded classes could retrieve from app-subclass technique a reference containing null, that simple. My main point is not about not subclassing application, but instead is not to retrieve the context statically. It should be retrieved on demand, passing it around from parents to children every single time. Bear with me: every single time. And it's not me explaining this, even if it seems to me it's not understood yet, it's Dianne Hackborn herself, and there's no doubts about her words.
  • ToolmakerSteve
    ToolmakerSteve over 4 years
    np. The essence of your answer - "start from a local context" is the important advice here (as Erich Douglass' answer said years ago). CLARIFICATION FOR OTHERS: the singleton is only needed when accessing your own custom globals. The original question was about accessing the application context anywhere. If someone is trying to do that, this doesn't help them do so - since you require a Context parameter myCtx. To merely access app context, this singleton is not needed - coder should simply do myCtx.getApplicationContext()....
  • Alessio
    Alessio over 4 years
    @ToolmakerSteve I showed the example as a singleton, because that's how it's explained in the Android docs I reference: "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.". So I showed exactly how you would do that, to pass it in getInstance() and retrieve the application context from it.
  • Alessio
    Alessio over 4 years
    @ToolmakerSteve so I disagree with what you say "If someone is trying to do that, this doesn't help them do so - since you require a Context parameter". Yes it does. It's simple: you shouldn't access your context everywhere, but you should pass it from parents to children all around, and children keep from it references of the application context. That's the proper way, anything else is purely wrong. I'm surprised after so many years this is not understood yet, and not because of me but because of Hackborn words and design of Android system.
  • Alessio
    Alessio over 4 years
    @ToolmakerSteve if you look at Flutter, which was designed 2 years ago, it uses the same pattern, passing the context on demand. So, there's no way you can fight the system, without been wrong (aka potential npe). And this is to access the global context: if you exclude activities and services classes, which other classes do you have that are not instantiated from an activity? I had only singletons or classes with pure static methods, I can't think of anything else. Do you?
  • Alessio
    Alessio over 4 years
    @ToolmakerSteve also let me state the obvious and make sure we're on the same page: I'm not suggesting to access the application context via MyHelper singleton. MyHelper is a class which needs to access a context, for instance to retrieve some resources or register a receiver, or whatever, in the doSomething() method. If another helper class AnotherHelper would need something similar, you would also need to pass a context in its getInstance(). And so forth, for all the classes which are not extending a context or have access to a context themselves
  • ToolmakerSteve
    ToolmakerSteve over 4 years
    @Alessio - I only commented again to clarify to anyone else coming here, that your answer isn't a solution to the original question, which was seeking a static way to access context. That is what I was referring to when I said "if someone is trying to do that ... this doesn't help them". Your answer is useful for the (different) situation where one has a context available, and wishes to use the app context in static methods. I just want readers to be clear for what purpose your answer is useful - and for what purpose it is not.
  • Alessio
    Alessio over 4 years
    @ToolmakerSteve I understood perfectly, and I disagree with you big time. I quote myself of few years ago: "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()". My answer answers the question, in such a way that there shouldn't be any way to access the context statically in someone's code, and she should access the context on demand instead. I think you're ignoring what I'm writing, please read it carefully it's all there
  • Dr. aNdRO
    Dr. aNdRO over 4 years
    This corehelper's object class will be initialised and can be used through out activities at later stage? Sorry I am new to kotlin
  • Yves Delerm
    Yves Delerm over 4 years
    Caution : is some rare cases, this block of code will not be called and that can cause a NPE crash : when app data is restored from the cloud, Application.onCreate() is not called at next start. stackoverflow.com/a/60597718/1333448
  • David Kariuki
    David Kariuki almost 4 years
    Is there anyway of preventing this leak on static context references?
  • Eugene Kartoyev
    Eugene Kartoyev almost 4 years
    No, since you are setting the context with getApplicationContext() it is not going to leak activity contexts. However, it may return null in a non-UI thread running beyond the activity.
  • Eugene Kartoyev
    Eugene Kartoyev almost 4 years
    In fact, this answer inspired me to use the convenient JQuery class naming. But it has nothing to do with JQuery. People should read better! Idea of using a WeakReference is beautiful!
  • Martin Zeitler
    Martin Zeitler over 3 years
    @EugeneKartoyev WeakReference is anything but recommended.
  • DADi590
    DADi590 about 3 years
    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.
  • DADi590
    DADi590 almost 3 years
    I 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.
  • DADi590
    DADi590 almost 3 years
    Then how do getApplicationContext() or getBaseContext() return a Context instance? Static variable internally and they just return it instead of relying on currentApplication()? Would be cool to go get the Context from where the 2 functions get it - but statically. I thought currentApplication() was where the other 2 would go, but it seems not to be. Wonder what is it then.
  • Tim Autin
    Tim Autin over 2 years
    For anyone doubting that using the getInstance singleton pattern + getApplicationContext does not cause a memory leak, check LocalBroadcastManager source code, which does exactly that.