270

This has me stumped, I was using this in Android 2.1-r8 SDK:

ProgressDialog.show(getApplicationContext(), ....);

and also in

Toast t = Toast.makeText(getApplicationContext(),....);

using getApplicationContext() crashes both ProgressDialog and Toast .... which lead me to this question:

What is the actual differences between a activity context and application context, despite sharing the wording 'Context'?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
t0mm13b
  • 34,087
  • 8
  • 78
  • 110
  • This is what I've found http://stackoverflow.com/questions/1561803/android-progressdialog-show-crashes-with-getapplicationcontext.... – t0mm13b Nov 08 '10 at 23:42
  • 14
    This should help clear some things up: [Context, What Context?](http://www.doubleencore.com/2013/06/context/) – Etienne Lawlor Jun 22 '13 at 05:56
  • possible duplicate of [When to call activity context OR application context?](http://stackoverflow.com/questions/7298731/when-to-call-activity-context-or-application-context) – n611x007 Jul 29 '14 at 14:47

7 Answers7

285

They are both instances of Context, but the application instance is tied to the lifecycle of the application, while the Activity instance is tied to the lifecycle of an Activity. Thus, they have access to different information about the application environment.

If you read the docs at getApplicationContext it notes that you should only use this if you need a context whose lifecycle is separate from the current context. This doesn't apply in either of your examples.

The Activity context presumably has some information about the current activity that is necessary to complete those calls. If you show the exact error message, might be able to point to what exactly it needs.

But in general, use the activity context unless you have a good reason not to.

Cheryl Simon
  • 46,552
  • 15
  • 93
  • 82
  • 2
    I got a 'java.lang.reflect.InvocationTargetException' when using `getApplicationContext`, interestingly enough, when I changed to `this`, it did not crash and work as expected....so if they are both instances of Context, why does one not work and the other does? This info will be of help to others I hope... :) thanks for your prompt answer... – t0mm13b Nov 08 '10 at 22:42
  • 2
    I'd need to see the full exception stacktrace to be able to say anything. However, as I said the context instances have different information. Presumably to show a dialog or toast on the screen requires information about the Activity that only the Activity instance has. – Cheryl Simon Nov 08 '10 at 23:53
  • 88
    I would say use the app context unless you have good reason not too (i.e. for dialogs or toasts). It's quite easy to run into memory leaks using activity contexts in different situations so best to be safe :) http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html – Dori Mar 30 '11 at 15:19
  • 11
    Dave Smith has posted a very good blog entry for understanding the usage of context, see [here](http://www.doubleencore.com/2013/06/context/). Make sure that you also read the comments! – ChrLipp Jul 03 '13 at 08:45
  • So, could be a good reason to pass to my application code classes to use system services that doesn't have anything to do with user interfaces? I have a singleton class as my main application class (not an extended class from the Application class that comes with android sdk, just my application gui-independent code) and I pass to the singleton instance the activity context to access the PackageManager and other services like that. Would it be better to use getApplicationContext() to avoid problems with destroyed activites? – Adrián Pérez Jul 21 '13 at 11:46
  • 1
    The thing is, that even Dianna Hackborn recommends to use activity context. http://stackoverflow.com/questions/5228160/what-exactly-does-using-the-application-context-mean/5228494#5228494 But she seems herself not be totally sure about this. – JacksOnF1re Mar 18 '15 at 12:58
242

I found this table super useful for deciding when to use different types of Contexts:

enter image description here

  1. An application CAN start an Activity from here, but it requires that a new task be created. This may fit specific use cases, but can create non-standard back stack behaviors in your application and is generally not recommended or considered good practice.
  2. This is legal, but inflation will be done with the default theme for the system on which you are running, not what’s defined in your application.
  3. Allowed if the receiver is null, which is used for obtaining the current value of a sticky broadcast, on Android 4.2 and above.
CommonSenseCode
  • 23,522
  • 33
  • 131
  • 186
39

This obviously is deficiency of the API design. In the first place, Activity Context and Application context are totally different objects, so the method parameters where context is used should use ApplicationContext or Activity directly, instead of using parent class Context. In the second place, the doc should specify which context to use or not explicitly.

lucas
  • 2,756
  • 19
  • 15
17

The reason I think is that ProgressDialog is attached to the activity that props up the ProgressDialog as the dialog cannot remain after the activity gets destroyed so it needs to be passed this(ActivityContext) that also gets destroyed with the activity whereas the ApplicationContext remains even after the activity gets destroyed.

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
user2779311
  • 1,688
  • 4
  • 23
  • 31
4

You can see a difference between the two contexts when you launch your app directly from the home screen vs when your app is launched from another app via share intent.

Here a practical example of what "non-standard back stack behaviors", mentioned by @CommonSenseCode, means:

Suppose that you have two apps that communicate with each other, App1 and App2.

Launch App2:MainActivity from launcher. Then from MainActivity launch App2:SecondaryActivity. There, either using activity context or application context, both activities live in the same task and this is ok (given that you use all standard launch modes and intent flags). You can go back to MainActivity with a back press and in the recent apps you have only one task.

Suppose now that you are in App1 and launch App2:MainActivity with a share intent (ACTION_SEND or ACTION_SEND_MULTIPLE). Then from there try to launch App2:SecondaryActivity (always with all standard launch modes and intent flags). What happens is:

  • if you launch App2:SecondaryActivity with application context on Android < 10 you cannot launch all the activities in the same task. I have tried with android 7 and 8 and the SecondaryActivity is always launched in a new task (I guess is because App2:SecondaryActivity is launched with the App2 application context but you're coming from App1 and you didn't launch the App2 application directly. Maybe under the hood android recognize that and use FLAG_ACTIVITY_NEW_TASK). This can be good or bad depending on your needs, for my application was bad.
    On Android 10 the app crashes with the message
    "Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?".
    So to make it work on Android 10 you have to use FALG_ACTIVITY_NEW_TASK and you cannot run all activities in the same task.
    As you can see the behavior is different between android versions, weird.

  • if you launch App2:SecondaryActivity with activity context all goes well and you can run all the activities in the same task resulting in a linear backstack navigation.

I hope I have added some useful information

DSoldo
  • 959
  • 10
  • 19
3

I think when everything need a screen to show ( button, dialog,layout...) we have to use context activity, and everything doesn't need a screen to show or process ( toast, service telelphone,contact...) we could use a application context

Dmobile
  • 31
  • 1
3

Use getApplicationContext() if you need something tied to a Context that itself will have global scope.

If you use Activity, then the new Activity instance will have a reference, which has an implicit reference to the old Activity, and the old Activity cannot be garbage collected.

Dhiraj Himani
  • 1,062
  • 12
  • 9