What's the Difference Between the Various Methods to Get an Android Context

What's the difference between the various methods to get an Android Context?

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.

Difference between getContext() , getApplicationContext() , getBaseContext() and this

  • View.getContext(): Returns the context the view is currently running in. Usually the currently active Activity.

  • Activity.getApplicationContext(): Returns the context for the entire application (the process all the Activities are running inside
    of). Use this instead of the current Activity context if you need a
    context tied to the lifecycle of the entire application, not just the
    current Activity.

  • ContextWrapper.getBaseContext(): If you need access to a Context from within another context, you use a ContextWrapper. The
    Context referred to from inside that ContextWrapper is accessed via
    getBaseContext().

getBaseContext or getContext? How do they differ?

getContext() Returns the context the view is currently running in. . Activity.

getBaseContext() : If you need access to a Context from within another context, you use this

What is 'Context' on Android?

Putting it simply:

As the name suggests, it's the context of the current state of the application/object. It lets newly-created objects understand what has been going on. Typically you call it to get information regarding another part of your program (activity and package/application).

You can get the context by invoking getApplicationContext(), getContext(), getBaseContext() or this (when in a class that extends from Context, such as the Application, Activity, Service and IntentService classes).

Typical uses of context:

  • Creating new objects:
    Creating new views, adapters, listeners:

     TextView tv = new TextView(getContext());
    ListAdapter adapter = new SimpleCursorAdapter(getApplicationContext(), ...);
  • Accessing standard common resources:
    Services like LAYOUT_INFLATER_SERVICE, SharedPreferences:

     context.getSystemService(LAYOUT_INFLATER_SERVICE)
    getApplicationContext().getSharedPreferences(*name*, *mode*);
  • Accessing components implicitly:
    Regarding content providers, broadcasts, intent

     getApplicationContext().getContentResolver().query(uri, ...);

What is the better way to get Context?

You should check out this question - which basicly covers the same as yours.

Also the Developer Docs on Avoiding memory leaks gives you a decent explanation of some situtations in which various of the methods are reasonable to use.

Difference between Activity Context and Application Context

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.

what is different between theses two context codes?

In Android, LayoutInflater is used to convert an xml file (activity_main.xml, fragment_login.xml, gallery_item.xml, etc.) into its coressponding View object.

XML file -> LayoutInflater -> View object in Java

To retrieve an instance of LayoutInflater, we have several options:

  • LayoutInflater.from(Context)

  • Context.getSystemService(String)

  • Activity.getLayoutInflater()

Back to your question

Code 1

LayoutInflater inflater = LayoutInflater.from(parent.getContext());

parent: The parent of the current item, in this case, parent is the RecyclerView

RecyclerView is a sub-class of View class, each View will have its own context, in this case, getContext() return the activity where you display the RecyclerView.

Code 2

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

In Android, when initializing an instance of an Adapter, we usually pass a Context instance via a constructor, like this.

class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Data> data;

public MyAdapter(Context context, List<Data> data) {
this.context = context;
this.data = data;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.gallery_item, parent, false);
return new ViewHolder(itemView);
}
}

In your case, because you do not assign any value to the context, that why the compiler throws that error.

Code 3

context = parent.getContext();

In this case, you don't need to pass a Context via a constructor, just use the context from parent.

class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Data> data;

public MyAdapter(List<Data> data) {
this.data = data;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.gallery_item, parent, false);
return new ViewHolder(itemView);
}
}

Inside onBindViewHolder(), you have 3 options to retrieve an instance of LayoutInflater:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();

// Option 1
LayoutInflater inflater = LayoutInflater.from(context);

// Option 2
LayoutInflater inflater2 = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

// Option 3
LayoutInflater inflater3 = ((Activity) context).getLayoutInflater();

View itemView = inflater.inflate(R.layout.gallery_item, parent, false);
return new ViewHolder(itemView);
}

I always choose option 1 because it's short.



Related Topics



Leave a reply



Submit