When to call activity context OR application context?

79,264

Solution 1

getApplicationContext() is almost always wrong. Ms. Hackborn (among others) have been very explicit that you only use getApplicationContext() when you know why you are using getApplicationContext() and only when you need to use getApplicationContext().

To be blunt, "some programmers" use getApplicationContext() (or getBaseContext(), to a lesser extent) because their Java experience is limited. They implement an inner class (e.g., an OnClickListener for a Button in an Activity) and need a Context. Rather than using MyActivity.this to get at the outer class' this, they use getApplicationContext() or getBaseContext() to get a Context object.

You only use getApplicationContext() when you know you need a Context for something that may live longer than any other likely Context you have at your disposal. Scenarios include:

  • Use getApplicationContext() if you need something tied to a Context that itself will have global scope. I use getApplicationContext(), for example, in WakefulIntentService, for the static WakeLock to be used for the service. Since that WakeLock is static, and I need a Context to get at PowerManager to create it, it is safest to use getApplicationContext().

  • Use getApplicationContext() when you bind to a Service from an Activity, if you wish to pass the ServiceConnection (i.e., the handle to the binding) between Activity instances via onRetainNonConfigurationInstance(). Android internally tracks bindings via these ServiceConnections and holds references to the Contexts that create the bindings. If you bind from the Activity, then the new Activity instance will have a reference to the ServiceConnection which has an implicit reference to the old Activity, and the old Activity cannot be garbage collected.

Some developers use custom subclasses of Application for their own global data, which they retrieve via getApplicationContext(). That's certainly possible. I prefer static data members, if for no other reason than you can only have one custom Application object. I built one app using a custom Application object and found it to be painful. Ms. Hackborn also agrees with this position.

Here are reasons why not to use getApplicationContext() wherever you go:

  • It's not a complete Context, supporting everything that Activity does. Various things you will try to do with this Context will fail, mostly related to the GUI.

  • It can create memory leaks, if the Context from getApplicationContext() holds onto something created by your calls on it that you don't clean up. With an Activity, if it holds onto something, once the Activity gets garbage collected, everything else flushes out too. The Application object remains for the lifetime of your process.

Solution 2

I think there's a lot of stuff that is poorly documented on the SDK site, this is one of them. The claim I'm going to make is that it seems as though it's better to default to using an application context and only use an activity context when you really need to. The only place where I've ever seen that you need an activity context is for a progress dialog. SBERG412 claims that you have to use an activity context for a toast message, yet the Android docs clearly show an application context being used. I've always used application context for toasts because of this Google example. If it's wrong to do so, then Google dropped the ball here.

Here's more to think about and review:

For a toast message, the Google Dev Guide uses the application context and explicitly say's to use it: Toast Notifications

In the dialogs section of the Dev guide, you see that an AlertDialog.Builder uses the application context, and then the progress bar uses an activity context. This isn't explained by Google. Dialogs

It seems like a good reason to use application context is when you want to handle configuration changes like an orientation change, and you want to retain objects which need a context like Views. If you look here: Run Time Changes There is a caution about using an activity context, which can create a leak. This can be avoided with an application context with the views that are to be retained (at least that's my understanding). In an app I'm writing, I intend to use an application context because I'm trying to hold over some views and other things on an orientation change, and I still want the activity to be destroy and recreated on orientation changes. Thus I have to use an app context to not cause a memory leak (see Avoiding memory Leaks). To me it seems there are plenty of good reasons to use the application context instead of an activity context, and to me it almost seems like you would use it more often than an activity context. That's what many Android books I've gone through seem to do, and that's what much of the Google examples I've seen do.

The Google documentation really makes it seem like using application context is perfectly fine in most cases, and in fact appears more often than using an activity context in their examples (at least the examples I've seen). If it's really such a problem to use application context, then Google really needs to place more emphasis on this. They need to make it clear, and they need to redo some of their examples. I wouldn't blame this entirely on inexperienced developers since the authority (Google) really makes it look like it's not a problem to use application contexts.

Solution 3

I used this table as a guidance for when to use the different types of Context such as Application context (i.e: getApplicationContext()) and activity context , also BroadcastReceiver context:

enter image description here

All merits go to original author here for more info.

Solution 4

Which context to use?

There are two types of Context:

  1. Application context is associated with the application and will always be same throughout the life of application -- it does not change. So if you are using Toast, you can use application context or even activity context (both) because toast can be displayed from anywhere with in your application and is not attached to a specific window. But there are many exceptions, one exception is when you need to use or pass the activity context.

  2. Activity context is associated with to the activity and can be destroyed if the activity is destroyed -- there may be multiple activities (more than likely) with a single application. And sometimes you absolutely need the activity context handle. For example, should you launch a new activity, you need to use activity context in its Intent so that the new launching activity is connected to the current activity in terms of activity stack. However, you may use application's context too to launch a new activity but then you need to set flag Intent.FLAG_ACTIVITY_NEW_TASK in intent to treat it as a new task.

Let's consider some cases:

  • MainActivity.this refers to the MainActivity context which extends Activity class but the base class (activity) also extends Context class, so it can be used to offer activity context.

  • getBaseContext() offers activity context.

  • getApplication() offers application context.

  • getApplicationContext() also offers application context.

For more information please check this link.

Solution 5

I was wondering why not to use Application Context for every operation which it supports. In the end it lowers chance of memory leak and missing null check for getContext() or getActivity() (when using injected application context or acquired through static method from Application). Statements, like the one by Ms. Hackborn to use Application Context only if needed, don't seem convincing for me without an explanation why. But it seems that I have found an unswear why:

have found that there are issues on some Android version / device combinations that do not follow these rules. For instance, if I have a BroadcastReceiver that is passed a Context and I convert that Context to an Application Context and then try to call registerReceiver() on the Application Context there are many instances where this works fine, but also many instances where I get a crash because of a ReceiverCallNotAllowedException. These crashes occur on a wide range of Android versions from API 15 up to 22. https://possiblemobile.com/2013/06/context/#comment-2443283153

Because it's not guaranteed that all operations described as supported by Application Context in the table below will work on all Android devices! enter image description here

Share:
79,264

Related videos on Youtube

Norfeldt
Author by

Norfeldt

Always learning something new 👨‍🔬

Updated on May 28, 2020

Comments

  • Norfeldt
    Norfeldt about 4 years

    There has been a lot of posting about what these two contexts are.. But I'm still not getting it quite right

    As I understand it so far: Each is an instance of its class which means that some programmers recommend you to use this.getApplicationContext() as often as possible in order to not "leak" out any memory. This is because the other this (getting the Activity instance context) points to an Activity that is being destroyed each time the user tilts the phone or leave the app etc.. Which apparently the Garbage Collector (GC) doesn't catch and therefore uses too much memory..

    But can anyone please come up with some really good coding examples where it would be the right thing to use this (getting the context of the current Activity instance) and the application context will be useless/wrong?

  • Norfeldt
    Norfeldt over 12 years
    Thank you very much for this answer. Another link I found before I read this answer might also help some people out. stackoverflow.com/questions/7298731/… - this link explain my concerns about leaking memory.
  • CommonsWare
    CommonsWare over 12 years
    @Norfeldt: FYI, the link in your comment links back to this answer.
  • Norfeldt
    Norfeldt over 12 years
    thank you.. this was the link: stackoverflow.com/questions/5796611/… it describes the memory leak that I was afraid of getting by using this
  • Admin
    Admin about 11 years
    I read somewhere that: "Use getApplicationContext() wherever possible. Since if we give Activity's context to something, the Garbage Collector will not remove the activity from memory, unless that 'something' is destroyed". Is it true?
  • CommonsWare
    CommonsWare about 11 years
    @djaqeel: The latter part of your quote is almost true. It is better phrased as "do not give an Activity context to something that will live longer than the Activity will, such as a static data member". However, you still only use getApplicationContext() when you know precisely why you need it in a given situation. Inflating a layout? Use the activity. Binding to a service, where you need that binding to survive a configuration change? Use getApplicationContext(), so the binding is not tied to the Activity instance.
  • Admin
    Admin about 11 years
    Okssss, so we must think before passing a context to something. I was happy giving application context wherever it ran without an exception; Now another 'thinking' step is added lol; I am not feeling good. Thanks anyways for the info.
  • ChrLipp
    ChrLipp almost 11 years
    Dave Smith has posted a very good blog entry for understanding the usage of context, see here. Make sure that you also read the comments!
  • Sever
    Sever over 10 years
    @CommonsWare: Why getApplicationContext() is almost always wrong? How can I see in android-developers.blogspot.de/2009/01/…, to avoid context-related memory leaks we should use context-application instead of a context-activity
  • CommonsWare
    CommonsWare over 10 years
    @Sever: I cover this in my answer. Dave Smith also has an excellent blog post covering contexts: doubleencore.com/2013/06/context His summary paragraph: "In most cases, use the Context directly available to you from the enclosing component you’re working within. You can safely hold a reference to it as long as that reference does not extend beyond the lifecycle of that component. As soon as you need to save a reference to a Context from an object that lives beyond your Activity or Service, even temporarily, switch that reference you save over to the application context."
  • Steve Schwarcz
    Steve Schwarcz about 10 years
    I completely agree. CommonsWare answer came as a little bit of a surprise to me. I'm glad I found this question, because int he Google documentation suggests that using getApplicationContext can be so dangerous.
  • 김준호
    김준호 about 9 years
    Hm.. Which Android OS version did you test? I've tested on 4.4.4 and it works well. Plus, as @Andi Jay mentioned, official Android developer document used application context in their sample code. developer.android.com/guide/topics/ui/notifiers/…
  • Ojonugwa Jude Ochalifu
    Ojonugwa Jude Ochalifu almost 9 years
    @Chinese name, yes it might work but sometime in the future of that app, it will also crash.Happened to me several times.
  • ARK
    ARK over 8 years
    @CommonsWare: Does the context changes during the lifecycle of an application?
  • CommonsWare
    CommonsWare over 8 years
    @akshayrajkore: I do not understand your question, sorry. Please consider using the "Ask Question" button to ask a fresh Stack Overflow question, where you can explain your concern in greater detail.
  • chakrapani
    chakrapani almost 8 years
    @CommonsWare, I agree with all your explanation, but I can't agree your last Point. For example: If we pass ApplicationContext to class A, and A is holding that ref., then, how come we are leaking A class object? if we clear all ref. to A class object, then it will be Garbage collected, even though A object is still has ref. to ApplicationContext. Please correct me , if I am wrong.
  • CommonsWare
    CommonsWare almost 8 years
    @chakrapani: "how come we are leaking A class object?" -- the bullet point is referring to cases where you have an Application that holds onto other things. Frequently, this would occur because you created a custom subclass of Application or used one from a library. However, we did not write Application, and so we do not know, for all versions of Android and all customizations made to it, what it might hold onto.
  • Jemshit Iskenderov
    Jemshit Iskenderov almost 8 years
    When i use Activity context in Toast, it leaks memory !
  • CybeX
    CybeX over 6 years
    What about the case where one needs to display a AlertDialog in the app e.g. An async process showing a result. An example of this may be: user clicks on download, this fires up a download request for downloadmanager, and when the finished signal is recieved, it should show a dialog e.g. "What do you want to do with this download?". My (hack) solution saves the most recent Activity in a static Application class, and requests the current Activity when the download is complete. However, I doubt this is the proper implementation. TL;DR How to display AlertDialog anywhere in app?
  • ExiRouS
    ExiRouS almost 6 years
    @KGCybeX If you want to display anything and anywhere in your app when download completes you should manually register a broadcast receiver on your activity that listens for a specific message that your download service will broadcast and do whatever you want upon receiving the message, or attach your activity to that service directly.
  • Francois Dermu
    Francois Dermu almost 6 years
    I have more than 10 years of experience in Android dev and I can tell you that, in most cases, you should actually do the exact opposite and ALWAYS USE APPLICATION CONTEXT unless you care about things like theme related resources that would vary per Activity or when handling Dialogs and starting Intents. The main issue with using Activity as a context is that you can leak it if you are not careful. @Norfeldt I suggest you take a second read of the answers and pick a different one as the solution. If I were you I would follow commonSenseCode's answer.
  • Norfeldt
    Norfeldt almost 6 years
    @FrancoisDermu thank you. The question is almost 7 years old and I haven't done Android since..