40

this often to reference to current context. But, at some case, why we must use getBaseContext() instead of this. (It means when use this will notice error).

Here is my example:

Spinner spinner = (Spinner) findViewById(R.id.spinner);
spinner.setAdapter(adapter);            
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?>arg0, View arg1, int arg2, long arg3){
       Toast.makeText(getBaseContext(),"SELECTED", Toast.LENGTH_SHORT).show(); //this line
    }

At above code, when I change getBaseContext() to this will receive error.

Who can explain for me, please.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
hqt
  • 29,632
  • 51
  • 171
  • 250
  • 22
    Do not use `getBaseContext()` or `getApplicationContext()` unless you know **exactly and specifically why** you are using it. Newcomers to Java should spend time learning Java before getting into Android programming, so you will learn about things like `OuterClass.this` and not be confused when you encounter the need for them. – CommonsWare Mar 07 '12 at 16:46
  • 3
    @CommonsWare can you give me a good link for this, please. (I'm just know the different of `getBaseContext()` and `getApplicationContext` – hqt Mar 07 '12 at 16:51
  • 7
    http://c2.com/cgi/wiki?InnerClass and http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html and http://juixe.com/techknow/index.php/2009/04/07/java-nested-inner-class-this/ and http://stackoverflow.com/questions/56974/keyword-for-the-outer-class-from-an-anonymous-inner-class – CommonsWare Mar 07 '12 at 16:57
  • 1
    it will give error if you pass `this` because you are passing current Activty context but this method require only `Context` object. – ρяσѕρєя K Mar 07 '12 at 20:06
  • 9
    You are getting an error with this because it refers to a Listener object, not Activity. – MSquare Apr 26 '13 at 10:27
  • see also http://stackoverflow.com/questions/6854265/getapplicationcontext-getbasecontext-getapplication-getparent – Paul Verest Jan 15 '15 at 07:27

7 Answers7

56
  1. getApplicationContext () returns the application context of the entire application life cycle,when application will destroy then it will destroy also.

  2. this the context returns the current context of the activity, belong to the activity, the activity is destroyed then it will destroy also.but in your case it will refers to the Spinner instance because we are using this within onItemSelected(AdapterView<?>arg0, View arg1, int arg2, long arg3) method which is from Spinner class and Spinner inherit this method from AdapterView.OnItemSelectedListener interface

  3. getBaseContext() is the method of ContextWrapper. And ContextWrapper is, "Proxying implementation of Context that simply delegates all of its calls to another Context. Can be subclassed to modify behavior without changing the original Context." (as per javadocs)..

and in your case :Spinner class is not subclass of Context or ContextWrapper class*

Toast.makeText(getBaseContext(),"SELECTED", Toast.LENGTH_SHORT).show();

means getBaseContext() is method of ContextWrapper and ContextWrapper is Proxying implementation of Context so indirectly we are passing an Context Class Object.

or we can also pass 'Activity.this' because Activity class is subclass of ContextWrapper class .

if you go with Android documentation then this method requires a Context class object:
public static Toast makeText (Context context, int resId, int duration)

so we are not able to pass an activity or class context means this to Toast.makeText which don't have a subclass of either Context or ContextWrapper class.

Pang
  • 9,564
  • 146
  • 81
  • 122
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
16

In your example this refers to newly created OnItemSelectedListener not to any context object. If this code is in activity you can write YourActivity.this instead of getBaseContext().

OnItemSelectedListener listener = new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?>arg0, View arg1, int arg2, long arg3){
       // this.equals(listener) == true;

       // getBaseContext() here means YourActivity.this.getBaseContext()
       // getBaseContext() called from outer context object (activity, application, service)
    }
}
Sergey Glotov
  • 20,200
  • 11
  • 84
  • 98
  • 2
    Does it true when say `each thread has it own context object` ? So, `onItemSelectedListener` is on different thread of UIThread, so we cannot use `this` keyword, right ? – hqt Mar 07 '12 at 16:41
  • 1. AFAIK, `onItemSelectedListener` is on UI thread. 2. It is not related to the threads. [`this` is a reference to the current object](http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html). In `onItemSelected()` method current object is `OnItemSelectedListener`. – Sergey Glotov Mar 07 '12 at 16:50
9

If this code is in the Activity MyActivity, you could also replace getBaseContext() by MyActivity.this.

This is because this refers to the OnItemSelectedListener instance, not to the Activity. getBaseContext() refers to the Activity context.

louiscoquio
  • 10,638
  • 3
  • 33
  • 51
5

OnItemSelected method this refers to the new OnItemSelectedListener instance that you used. getBaseContext is you outer class.

Malwinder Singh
  • 6,644
  • 14
  • 65
  • 103
Raz
  • 8,918
  • 3
  • 27
  • 40
  • 2
    same question as I have asked Sergey, Does it true when say each thread has it own context object ? So, onItemSelectedListener is on different thread of UIThread, so we cannot use this keyword, right ? Thanks :) – hqt Mar 07 '12 at 16:42
  • 1
    AFAIK `this` refer to the instance where you are. If you're in an inner (or anonymous) class, it refers to that inner class. No matter if you're in the thread 1 or 30. – louiscoquio Mar 07 '12 at 16:49
  • louiscoquio is right. The thread doesn't have any relation to the context. "this" refers to the instance. – Raz Mar 08 '12 at 07:31
4

getBaseContext() refers to Activity.this

like we want to showing Toast on click of button, we never user this we use Activty.this. So that our Toast display till we are on the same activity. But if we use getApplicationContext() than our Toast will display even we switch the activity.

sharma_kunal
  • 2,152
  • 1
  • 28
  • 28
3

The getBaseContext() Sometimes confuses new comers to android, instead one could also use the ActivityName which is the current activity in which your are working. so ActivityName.this will replace getBaseContext()

EdemOne
  • 31
  • 2
3

If you use this refers OnItemSelectedListener .And its Interface not Class .so it's gives you error ,,, Always Use if you are in Activity YourActivityName.this

Samir Mangroliya
  • 39,918
  • 16
  • 117
  • 134