53

I am trying ProgressDialog. But I am confused.

1. pd=ProgressDialog.show(MainActivity.this, "", "Fething data");

when I do use (MainActivity.this) then it is ok. But

2. pd=ProgressDialog.show(getApplicationContext(), "", "Fething data");

When I do use (getApplicationContext()) it is ERROR.

What is problem for this progressDialog?

What is different between (MainActivity.this) vs (getApplicationContext())

and when I use it the perfect time?

For getApplicationContext() Error is:

04-09 15:05:37.453: E/AndroidRuntime(9980): FATAL EXCEPTION: main
04-09 15:05:37.453: E/AndroidRuntime(9980): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.view.ViewRootImpl.setView(ViewRootImpl.java:571)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:246)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.app.Dialog.show(Dialog.java:281)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.app.ProgressDialog.show(ProgressDialog.java:116)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.app.ProgressDialog.show(ProgressDialog.java:99)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.app.ProgressDialog.show(ProgressDialog.java:94)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at com.example.shikkok_services.MainActivity$2.onClick(MainActivity.java:27)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.view.View.performClick(View.java:4204)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.view.View$PerformClick.run(View.java:17355)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.os.Handler.handleCallback(Handler.java:725)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.os.Handler.dispatchMessage(Handler.java:92)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.os.Looper.loop(Looper.java:137)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at android.app.ActivityThread.main(ActivityThread.java:5041)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at java.lang.reflect.Method.invokeNative(Native Method)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at java.lang.reflect.Method.invoke(Method.java:511)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
04-09 15:05:37.453: E/AndroidRuntime(9980):     at dalvik.system.NativeStart.main(Native Method)
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
AndyError
  • 561
  • 1
  • 6
  • 10

7 Answers7

110

Which context to use?

There are two types of Context:

Application context is associated with the application and will always be the 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 within your application and is not attached to a specific window. But there are many exceptions. One such exception is when you need to use or pass the activity context.

Activity context is associated with the activity and can be destroyed if the activity is destroyed; there may be multiple activities (more than likely) with a single application. 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 newly-launched activity is connected to the current activity in terms of activity stack. However, you may also use application's context 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.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Zohra Khan
  • 5,182
  • 4
  • 25
  • 34
  • thanks for answer bro...@Zohra khan, but i have some confuse, MainActvity is Applecation and Actvitiy is context?? – AndyError Apr 09 '14 at 16:16
  • @user3515725 As the name suggest MainActivity is activity and its part of a application. There are various components in an application like service, activity, broadcast receiver et. al. MainActvity.this is activity context. Hope I am clear. Please accept my answer. – Zohra Khan Apr 09 '14 at 17:12
  • You can check androidhive.info for more on Android. – Zohra Khan Apr 09 '14 at 17:17
  • This part of your answer is just wrong: _"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."_, The `Context` used to call `startActivity()` is relevant, however the `Context` used as the first parameter to the `Intent` constructor `new Intent(context, Foo.class)` can be any `Context`. – David Wasser Aug 12 '16 at 13:07
  • It would be useful if you would fix your answer to make this clear. A lot of people are very confused about this. – David Wasser Aug 12 '16 at 13:08
  • I'm implementing an `AlertDialog`, and it seems that `MainActivity.this` and `getBaseContext()` are not interchangeable. Is there anything equivalent to a `MainActivity.this`? – Minh Nghĩa Jun 17 '20 at 10:48
20
  • MainActivity.this only works if you are in an inner class of MainActivity.

  • If you are in MainActivity itself, just use this.

  • If you are in another class entirely, you need to pass it an instance of a context from the Activity you are in.

Hope this helps..

Sanoop Surendran
  • 3,484
  • 4
  • 28
  • 49
Varun
  • 542
  • 1
  • 7
  • 17
18

This explanation is probably missing some subtle nuances but it should give you a better understanding of why one works but the other doesn't.

The difference is that MainActivity.this refers to the current activity (context) whereas the getApplicationContext() refers to the Application class.

The important differences between the two are that the Application class never has any UI associations and as such has no window token.

Long story short: For UI items that need context, use the Activity.

Ishaan Javali
  • 1,711
  • 3
  • 13
  • 23
triggs
  • 5,890
  • 3
  • 32
  • 31
  • thansk @triggs for answare.application class is MainACtivity and current activity is xml layout?? – AndyError Apr 09 '14 at 16:03
  • No, both the Application class and an Activity class can be considered a type of Context. The Application class can be thought of as the whole app but an Activity is what is currently on screen at any time and the xml layout is just the UI of an Activity. – triggs Apr 09 '14 at 16:41
  • could you define what is window token? – blackHawk Aug 18 '17 at 13:43
  • 1
    its just a ref to the Window, which is basically somewhere to put ui elements. An Activity has a Window, so you can put Views in it, Application Context has no window, so there's no where to put Views. – triggs Aug 18 '17 at 15:01
7

MainActivity.this refers to the the current activity (context) where the getApplicationContext() refers to the Application class.

The getApplicationContext() method return the context of the single, global Application object of the current process. This generally should only be used if you need a Context whose lifecycle is separate from the current context, that is tied to the lifetime of the process rather than the current component.

MainActivity.this will change when activity destroyed and re-created, getApplicationContext() will change when the application killed and re-started.

1

mainActivity gives the context of the current Activity. context depends on activity's lifecycle. getApplicationContext() gives the context of the application and depends on the application's lifecycle.

ppreetikaa
  • 1,149
  • 2
  • 15
  • 22
0

This is what the developer.android.com says:

Return the context of the single, global Application object of the current process. This generally should only be used if you need a Context whose lifecycle is separate from the current context, that is tied to the lifetime of the process rather than the current component.

In general, use ..Activity.this instead of getApplicationContext();

Further reading: developer.android.com/reference/android/content/Context.html#getApplicationContext()

andMarkus
  • 960
  • 1
  • 8
  • 16
0

MainActivity.this has more information. You can think of

MainActivity.this = getApplicationContext() + UI related information.

Why getApplicationContext() did not work here

2. pd=ProgressDialog.show(getApplicationContext(), "", "Fething data");

is because the ProgressDialog needs UI information. ProgressDialog may or may not be full screen size. If it only takes a portion of the screen, what should the background be? Should it be black, white, or your MainActivity's layout?

Which version of context to use depends on your use cases.

Non-UI-related context usages:

context.getFilesDir()  // File I/O
context.getColor()     // Preset values, strings, colors, pictures...

// create intent
Intent intent = new Intent(context, SettingsActivity.class);

// start new activity
context.startActivity(intent);

...

UI-related context usages (i.e. XXXActivity.this):

// create Adapters for you UI element
myRecyclerViewAdapter = new myRecyclerViewAdapter(this);

// Make new dialogs, i.e. ProgressDialog, AlertDialog...
new AlertDialog.Builder(this)...

// Set current layout fullscreen to get rid of status bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN)

// Set attributes such as colors based on theme
TypedValue typedValue = new TypedValue();
this.getTheme().resolveAttribute(R.attr.colorBackground, typedValue, true);
@ColorInt int colorBasedOnTheme = typedValue.data;

When you pass context to other classes, the Non-UI version context (i.e. getApplicationContext()) will not expire because it lives as long as your application itself. But the UI version context (i.e. XXXActivity.this) will expire because it only lives as long as your XXXActivity. And if an object holds a context(XXXActivity.this) out-lives the original XXXActivity, there will be problems: memory leak, null point exception, undefined behaviours, etc.

BlowMyMind
  • 435
  • 4
  • 6