context vs views - android

can anyone explain the difference between context and views and when do we go for context or view ? In most of the program I find either context or view being passed to certain methods , what is actual need of passing context or view to methods?

This is a strange question. View describes one element of your ui. It can have onClickListeners, properties and so on. But every view is created in some context, usually Activity's context.
Context as itself is something like environment your code is executed in. It has access to ui(if it is an activity), it can contain some global data(application context), and has access to the resources(all of the contexts). Also, context allows you to perform common android operations like broadcasting intents, start activities and services.
So, views should be passed when you want to do something with a particular view.
Context is passed when you need access to resources, global data or ui context, or launch other android components.

We need to understand how View is constructed and what is Context.
View has three constructors, all of which use Context as an argument.
In Activity, if view is inflated programmatically as against in XML, view is inflated a View is by using LayoutInflater.
LayoutInflater takes Context as an argument and internally saves it in a class level field.
LayoutInfater layoutinflater = LayoutInflater.from(this);
where "this" is the Activity instance.
When inflater inflates view i.e. :
inflater.inflate(R.id.some_view, parent, null),
it is internally passing the saved context field to the constructor of View.
View always takes a Context as an argument and this is obvious because views live in some Context which is the Activity.
To answer your question, when context is needed to be passed to a method which itself is in Activity, you can write "this". If method is not in Activity, and you need to pass Context, then remember that View which has taken Context as a parameter, saves the object reference in a class level field. We can get this object reference by writing view.getContext().

Related

Why we need to pass Context to a View?

Each Activity is a Context.
Each View needs a Context.
Is it correct to say that when we pass the Context to a View, we are basically adding a View to a certain Activity by passing the Context?
The context is required because it provides access to many android system resources.
It provides theme information so that the view can properly draw itself with the given theme, but also provides a way to access other types of resource.
It provides access to layout inflater which may be needed to create child views.
You can use context to access String resources (and other resources). You may need Strings to add an appropriate text label to your view.
If you need access to shared preferences, that can be accessed via a context.
It is not correct to say that you are adding a view to an activity if you have passed that activity to the view as a context. The activity is simply providing the context needed by the view.
Here is a more thorough answer explaining the purpose of a context

Does inflater require Activity's context?

I sometimes inject link to LayoutInflater by Dagger, and produce it in module from Application context like this: LayoutInflater.from(application);. It reduces lines of code.
But colleges tell me that it is wrong way, and it has to be given from Activity context by LayoutInflater.from(MainActivity.this);
Is it true? Does behaviour of layout inflater depend on type of context?
Yes it is true. There's a big difference considering styles.
The LayoutInflater creates the views by calling their constructors. There it passes the context you passed to it. So if you use the application context instead of an activity context you might lack some information.
It's the same issue like using application context for creating views directly. Activities may define different styles and their contexts wrap these information.
Taking into consideration how you could get it, there's not a big difference. Internally LayoutInflater.cloneInContext(Context) is called to apply different context configurations.
Create a copy of the existing LayoutInflater object, with the copy pointing to a different Context than the original. This is used by ContextThemeWrapper to create a new LayoutInflater to go along with the new Context theme.
With the application context you don't get this.
If I understand things correctly, in case of using application context for creating LayoutInflater you have a chance to loose your Theme settings. See here for more details.
UPDATED
From source code of layout inflater:
Object[] args = mConstructorArgs;
args[1] = attrs;
constructor.setAccessible(true);
final View view = constructor.newInstance(args);
if (view instanceof ViewStub) {
// Use the same context when inflating ViewStub later.
final ViewStub viewStub = (ViewStub) view;
viewStub.setLayoutInflater(cloneInContext((Context) args[0]));
}
return view;
As you can see, your context (in your case application context) passes in constructions of View. It means that scope of your view will be application, not activity.
If we Application context means, the inflater instance exist throughout the application until the app is killed. In other case, if we use activity context the inflater instance will be removed once activity is destroyed.
you can use getApplicationContext() when you know you need a Context for something that may live longer than any other likely Context you have at your disposal like services .
So It is best practice to use activity context when you dont need your object that will hold for long time or to global scale.
Hope it will help.

how to get fragment object from context

Is it possible to get the fragment object from the context object? I am basically trying to access the fragment object from a SearchView class that i extended. Since context is the only object passed to the SearchView constructor, i was hoping to somehow get a reference to the fragment from it.
I know that we can get it from within an activity by using getSupportFragmentManager().findFragmentById(R.id.xxx). But getSupportFragmentManager() is available only in a FragmentActivity class. Is there someway to access the fragment from another class?
If you don't mess with the normal way a View is built then the Context reference that you receive in the constructor of a View is the Activity(a Context) where the View is being used. So, you have the option of casting that Context to an Activity reference and from there you can use one of the various ways to access the desired Fragment.

When will a View method's Context param not be equivalent to .getContext()

If you are able to call view.getContext() to return the Activity's context under which the view instance is currently being rendered, why do some of the View family methods take a Context as a parameter?
Could this not be implicit, or are there occassions when getContext() is different from a Context passed to one of these methods?
Here is an example: http://developer.android.com/reference/android/widget/ViewAnimator.html#setInAnimation(android.content.Context, int)
Many thanks for clearing this up
view.getContext() actually return's your Activity's context, not application's. That is the reason you need to provide such context when initializing a new View.
And there's a difference between these two contexts. An Activity's context is attached to that particular activity's life-cycle. However, the application's context is referring to application's life-cycle.
For more info, read this.
I recently read some API returning IBinder, like getWindowToken() and getApplicationWindowToken(). Quoting the latter:
Retrieve a unique token identifying the top-level "real" window of the
window that this view is attached to. That is, this is like
getWindowToken(), except if the window this view in is a panel window
(attached to another containing window), then the token of the
containing window is returned instead.
Maybe this IPC mechanism has something to do with the View API. Android designers are not stupid or zealous: if they require a Context to build a View, it means that a Context is all they need, so building a View must be possible with an application context, a service context and -of course!- an activity context, but an activity is not required. The Context is just an umbrella API to retrieve resources, accessing databases, building intents and the like.
This is not the answer to your question, but maybe can serve as a helper point. I'm looking for the answer myself. Hope your question gets the attention it deserves.

Can all views within an activity be assumed to have same Context?

I have noticed with Views in android that sometimes getContext() returns the containing activity, whilst other times it returns the application.
For the purposes of cleaning up pending remote image loads (which I am loading via an external load manager class), can I safely assume that all views on a particular Activity will share the same context? I was thinking of passing the activity object to cleanup and removing all views with a context matching that activity. I am sure it will depend on a few things to do with the way the views were created, just wondering what those are.
This actually works very well in my testing. Essentially the Context passed to the layout inflater or view constructor will be the context of the view throughout its lifetime (makes sense). The only time these will mismatch is if you use different contexts (such as the application context) to inflate some parts of your layout... the context for views inflated via the activity's setContentView() will have the Activity set as theirs.

Categories

Resources