Friday, June 1, 2012

Android - what"s the difference between the various methods to get a Context?


In various bits of Android code I've seen:




public class MyActivity extends Activity {
public void method() {
mContext = this; // since Activity extends Context
mContext = getApplicationContext();
mContext = getBaseContext();
}
}



However I can't find any decent explanation of which is preferable, and under what circumstances which should be used.



Pointers to documentation on this, and guidance about what might break if the wrong one is chosen, would be much appreciated.


Source: Tips4all

6 comments:

  1. I agree that documentation is sparse when it comes to Contexts in Android, but you can piece together a few facts from various sources.

    This blog post on the official Google Android developers blog was written mostly to help address memory leaks, but provides some good information about contexts as well:


    In a regular Android application, you
    usually have two kinds of Context,
    Activity and Application.


    Reading the article a little bit further tells about the difference between to the two and why you might want to consider using the application Context (Activity.getApplicaitonContext()) rather than using the Activity context ("this"). Basically the Application context is associated with the Applicaiton and will always be the same throughout the life cycle of you app, where as the Activity context is associated with the activity and could possible be destroyed many times as the activity is destroyed during screen orientation changes and such.

    I couldn't find really anything about when to use getBaseContext() other than a for a one liner from Dianne Hackborn, one of the Google engineers working on the Android SDK:


    Don't use getBaseContext(), just use
    the Context you have.


    That was from a post on the android-developers newsgroup, you may want to consider asking your question there as well because a handful of the people working on Android actual monitor that newsgroup and answer questions.

    So overall it seems preferable to use the global application context when possible.

    ReplyDelete
  2. First, I agree that we should use appcontext whenever possible. then "this" in activity. i've never had a need for basecontext.

    In my tests, in most cases they can be interchanged. In most cases, the reason you want to get a hold of a context is to access files, preferences, database etc. These data is eventually reflected as files in your app's private data folder (/data/data/). No matter which context you use, they'll be mapped to the same folder/files so you are OK.

    That's what I observed. Maybe there are cases you should distinguish them.

    ReplyDelete
  3. I read this thread a few days ago, asking myself the same question. My decision after reading this was simple: always use applicationContext.

    However, I encountered a problem with this, I spent a few hours to find it, and a few seconds to solve it... (changing one word...)

    I am using a LayoutInflater to inflate a view containing a Spinner.

    So here are two possibilities:

    1)

    LayoutInflater layoutInflater = LayoutInflater.from(this.getApplicationContext());


    2)

    LayoutInflater layoutInflater = LayoutInflater.from(this.getBaseContext());


    Then, I am doing something like this:

    // managing views part
    View view = ContactViewer.mLayoutInflater.inflate(R.layout.aViewContainingASpinner, theParentView, false);
    Spinner spinner = (Spinner) view.findViewById(R.id.theSpinnerId);
    String[] myStringArray = new String[] {"sweet","love"};

    // managing adapter part
    // The context used here don't have any importance -- both work.
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this.getApplicationContext(), myStringArray, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);

    theParentView.addView(view);


    What I noticed: If you instantiated your linearLayout with the applicationContext, then when you click on the spinner in your activity, you will have an uncaught exception, coming from the dalvik virtual machine (not from your code, that's why I have spent a lot of time to find where was my mistake...).

    If you use the baseContext, then that's all right, the context menu will open and you will be able to choose among your choices.

    So here is my conclusion: I suppose (I have not tested it further) than the baseContext is required when dealing with contextMenu in your Activity...

    The test has been done coding with API 8, and tested on an HTC Desire, android 2.3.3.

    I hope my comment have not bored you so far, and wish you all the best. Happy coding ;-)

    ReplyDelete
  4. In some cases you may use Activity context over application context when running something in a thread. When thread completes execution and you need to return the result back to the caller activity, you need that context with a handler.

    ((YourActivity) context).yourCallbackMethod(yourResultFromThread, ...);

    ReplyDelete
  5. I've only used this and getBaseContext when toasting from an onClick (very green noob to both Java and android). I use this when my clicker is directly in the activity and have to use getBaseContext in an anonymous inner clicker. I'm guessing that is pretty much the trick with getBaseContext, it is perhaps returning the context of the activity in which the inner class is hiding.

    ReplyDelete
  6. This link might help you. Go through this..

    ReplyDelete