Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between the various methods to get an Android 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.

like image 988
Alnitak Avatar asked Jun 22 '09 12:06

Alnitak


People also ask

What is the difference between getContext () getApplicationContext () getBaseContext () and this?

getApplicationContext() - Returns the context for all activities running in application. getBaseContext() - If you want to access Context from another context within application you can access. getContext() - Returns the context view only current running activity.

Which of the following are the two types of context in Android?

In the below program you will see that we have created a textView dynamically and passed context. This context is used to get the information about the environment. This example demonstrates how do I display context in an android textView.

What is the difference between activity context and Applicationcontext?

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.


2 Answers

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 the two and when you might want to consider using the application Context (Activity.getApplicationContext()) rather than using the Activity context this). Basically the Application context is associated with the Application and will always be the same throughout the life cycle of your app, where as the Activity context is associated with the activity and could possibly 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 post 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.

like image 55
snctln Avatar answered Nov 02 '22 02:11

snctln


Here's what I've found regarding the use of context:

1) . Within an Activity itself, use this for inflating layouts and menus, register context menus, instantiating widgets, start other activities, create new Intent within an Activity, instantiating preferences, or other methods available in an Activity.

Inflate layout:

View mView = this.getLayoutInflater().inflate(R.layout.myLayout, myViewGroup); 

Inflate menu:

@Override public boolean onCreateOptionsMenu(Menu menu) {     super.onCreateOptionsMenu(menu);     this.getMenuInflater().inflate(R.menu.mymenu, menu);     return true; } 

Register context menu:

this.registerForContextMenu(myView); 

Instantiate widget:

TextView myTextView = (TextView) this.findViewById(R.id.myTextView); 

Start an Activity:

Intent mIntent = new Intent(this, MyActivity.class); this.startActivity(mIntent); 

Instantiate preferences:

SharedPreferences mSharedPreferences = this.getPreferenceManager().getSharedPreferences(); 

2) . For application-wide class, use getApplicationContext() as this context exist for the lifespan of the application.

Retrieve the name of the current Android package:

public class MyApplication extends Application {         public static String getPackageName() {         String packageName = null;         try {             PackageInfo mPackageInfo = getApplicationContext().getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), 0);             packageName = mPackageInfo.packageName;         } catch (NameNotFoundException e) {             // Log error here.         }         return packageName;     } } 

Bind an application-wide class:

Intent mIntent = new Intent(this, MyPersistent.class); MyServiceConnection mServiceConnection = new MyServiceConnection(); if (mServiceConnection != null) {     getApplicationContext().bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE); } 

3) . For Listeners and other type of Android classes (e.g. ContentObserver), use a Context substitution like:

mContext = this;    // Example 1 mContext = context; // Example 2 

where this or context is the context of a class (Activity, etc).

Activity context substitution:

public class MyActivity extends Activity {     private Context mContext;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);                 mContext = this;     } } 

Listener context substitution:

public class MyLocationListener implements LocationListener {     private Context mContext;     public MyLocationListener(Context context) {         mContext = context;     } } 

ContentObserver context substitution:

public class MyContentObserver extends ContentObserver {     private Context mContext;     public MyContentObserver(Handler handler, Context context) {         super(handler);         mContext = context;     } } 

4) . For BroadcastReceiver (including inlined/embedded receiver), use the receiver's own context.

External BroadcastReceiver:

public class MyBroadcastReceiver extends BroadcastReceiver {     @Override     public void onReceive(Context context, Intent intent) {         final String action = intent.getAction();         if (action.equals(Intent.ACTION_SCREEN_OFF)) {             sendReceiverAction(context, true);         }         private static void sendReceiverAction(Context context, boolean state) {             Intent mIntent = new Intent(context.getClass().getName() + "." + context.getString(R.string.receiver_action));             mIntent.putExtra("extra", state);             context.sendBroadcast(mIntent, null);         }     } } 

Inlined/Embedded BroadcastReceiver:

public class MyActivity extends Activity {     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {         @Override         public void onReceive(Context context, Intent intent) {             final boolean connected = intent.getBooleanExtra(context.getString(R.string.connected), false);             if (connected) {                 // Do something.             }         }     }; } 

5) . For Services, use the service's own context.

public class MyService extends Service {     private BroadcastReceiver mBroadcastReceiver;     @Override     public void onCreate() {         super.onCreate();         registerReceiver();     }     private void registerReceiver() {         IntentFilter mIntentFilter = new IntentFilter();         mIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);         this.mBroadcastReceiver = new MyBroadcastReceiver();         this.registerReceiver(this.mBroadcastReceiver, mIntentFilter);     }  } 

6) . For Toasts, generally use getApplicationContext(), but where possible, use the context passed from an Activity, Service, etc.

Use context of the application:

Toast mToast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG); mToast.show(); 

Use context passed from a source:

public static void showLongToast(Context context, String message) {     if (context != null && message != null) {         Toast mToast = Toast.makeText(context, message, Toast.LENGTH_LONG);         mToast.show();     } } 

And last, don't use getBaseContext() as advised by Android's framework developers.

UPDATE: Add examples of Context usage.

like image 39
ChuongPham Avatar answered Nov 02 '22 01:11

ChuongPham