in my project I am passing a context of an activity to a helper class. Now, is it possible to use that context and find the views from that activity? Basically, I would like to find the views by id, but just using a context object.
How can I achieve this?
Provided you stored your context in a private reference, do this (MonoDroid)
View parent = ((Activity)_context).Window.DecorView.FindViewById(Android.Resource.Id.Content);
In Raw Android it'd look something like:
View parent = ((Activity)mContext).getWindow().getDecorView().findViewById(android.R.id.content)
Activity is a Context, so if you actually pass your Activity to a helper class, you can just:
void someMethodInHelperClass(Context c) {
if(c instanceof Activity) {
((Activity)c).findViewById(R.id.someviewid);
}
}
Of course it will be much easier if you change your method to:
void someMethodInHelperClass(Activity c) {
Related
I was reading fragment documentation and found this:
Caution: If you need a Context object within your Fragment, you can call getContext(). However, be careful to call getContext() only when the fragment is attached to an activity. When the fragment isn't attached yet or was detached during the end of its lifecycle, getContext() returns null
So my question is what is the best place to call getContext() inside the fragment. Like i can call it in onCreateView, or onCreate() or onAttach() on any other place.
I am asking this because recently I got a crash of null pointer using getContext in my fragment. So I thought I should create a global Context object and access it inside the fragment. But then I came across this text from official documentation so I am a bit confused what would be the best place to initialize this Context object.
It all depends what you need that Context for. Sometimes it's just fine to call getApplicationContext(), in other cases it may be needed to use what you are given in onAttach() or call getActivity() if you are in Fragment code. Some are also providing own Application subclass, exposing static method like getAppContext().
In any case, AVOID saving the context as it may lead to memory leak. Get it dynamically when needed only.
As a lot of wrong answers are given, I'll provide what's the best way to handle context inside fragments.
The best solution is checking if the context has a value whenever you need it.
You can do it by wrapping the code in which you access the fragment in 2 ways:
if (getContext() != null) { /* code here */ }
or, as stated in the documentation there's this method:
isAdded()
which: "Return true if the fragment is currently added to its activity." -reference
Again: please AVOID saving the context in a local fragment's variable.
You can do something like this in your fragment.
#Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
// After this point the context is initialized.
context=activity;
}
NOTE: I don't really get it why it is so not liked this answer.
First af all, depending on the version of android(which was not mentioned), of course the OnAttach is deprecated, it has to be checked.
Next:
I think that if you need cobntext somewhere, you can make a private or protected variable in Fragment, so the context is destroyed when it is garbage collected.
protected MainActivity activity;
Make sure you hold this variable dearly and its reference is not passed to other classes.
This should do the job.
You can implement your logic like this :
private Context mContext;
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
#Override
public void onDetach() {
mContext = null;
super.onDetach();
}
When you required to use context,
if(mContext != null) {
//Add your logic here
}
I am trying of access a view from a non activity class, but I am not sure how to do it
After looking at some other sources, I understand I must pass the Context like this
public Manager(Context c) {
context = c;
}
but when I try c.findViewById() it doesnt work. How do you do this?
Try this
public Manager(Activity a) {
Activity = a;
}
then do
a.findViewById
If you make your view a public static variable, you can access it from anywhere in your application.
for example:
In your Activity class, use
public static TextView mTextView = null;
In its onCreate(), initialize the TextView.
Now from any other class, you can always use:
myActivity.mTextView
to access the TextView
I am trying to call this method:
public static void trackFunXStartActivity(Activity a)
{
s.startFunXActivity(a);
}
I'm trying to call it using this code in my LayoutsActivity.java:
public void onStart() {
TrackFunX.trackFunXStartActivity(LayoutsActivity);
}
but I'm not sure how to create or reference the Activity that I can pass to trackFunXStartActivity(Activity a). I don't think I can pass LayoutsActivity as an Activity.
How do I go about instantiating or reference an activity in LayoutsActivity.java to pass to trackFunXStartActivity.
I'm a Android newbie and have done some searches on StackOverflow but didn't see anything to help with this questions.
Thanks
take a static context for the LayoutsActivity like
static Context context;
and in the oncreate method use
context = LayoutsActivity.this
and finally you can use this context in the class where you need
After read this topic avoiding memory leaks some doubts arouse.
If I need to use an activity context (example: inflate a view in a PopupWindow class to show a popup) how can I hold the context of actual activity to do it? If I need to avoid a static context reference the only way to do it is creating an attribute in my class? And all the other classes I'll need the actual activity context I need to do it?
update-
I want to use this actual activity context in many classes that don't inherited Context, like I use with the application Context in my Application class that has a static method called getApplicationContext() declared. This method follows the Singleton Design Pattern and works fine.
Working from the code you linked in the comments, why not do this:
//my main activity
public class ExampleStaticReferenceActivity extends Activity {
//...
public void methodCalledWhenUserPressesButton(){
LinearLayout masterLayout = (LinearLayout) findViewById(R.id.masterLayout);
//now passing a reference to the current activity - elevine
masterLayout.addView(ButtonCreator.createButton(this));
}
}
//this class is in another package
public class ButtonCreator {
//added a Context parameter - elevine
public static Button createButton(Context context) {
Button button;
button = new Button(context);
//... some configurations for button
return button;
}
}
That will crash your Application since Your Activity will be killed by OS when it runs out of Resources thus Context will also be null.. And its meaningless to give A background Activities Instance when you want to show pop up in the Foreground Activity.. What the Blog says is avoid passing activity.this where even getApplicationContext() can do the job..
What is the correct way to implement a constructor in android?
It seems that in an Activity or Service 'onCreate()' is where the magic happens.
The reason I ask is because I would like to be sure I'm doing the right thing declaring
attributes in the top of my classes (Context in particular) and then setting the attribute values inside onCreate.
// Activity launched via an Intent, with some 'extras'
public class SomeActivity extends Activity {
private Context context;
private String foo;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the object attribute for later use, good or Bad to do this?
context = getApplicationContext();
Intent fooIntent = getIntent();
foo = fooIntent.getStringExtra("foo");
}
private void someMethodThatNeedsContext() {
// For example:
Cursor c = this.context.getContentResolver().query(foo, xxx, xxx);
// Or is it better practice to:
// A) Pass the context as a local variable to this method
// B) Use getApplicationContext() locally when needed
}
}
Maybe either of these options is ok, and I'm over thinking it?
Any specific reading and/or suggestions you may have would greatly be helpful to me.
Yes, you are correct that initialization is supposed to take place in onCreate(). You don't really need neither to store a reference to a context, nor to call getApplicationContext(). Your activity is a context itself, so you just use wherever you need a context. For example, making a toast within an activity:
Toast.makeToast(this, "Some text", Toast.LENGTH_LONG).show();
Option B - Since you can call getApplicationContext() from any non-static methods in your Activity class.
In fact, Activity is derived from Context too (Somewhere in the inheritance tree..) so you can just do:
Cursor c = getContentResolver()....
You don't have to keep a reference to a context. Especially not static, that can cause problems.
And you are correct - since you usually don't create your own constructor for Activities, you put the code for construction in onCreate.
You are writing a method inside your activity, so you can call getApplicationContext() anywhere in your code, you don't need to use a local variable :
Cursor c = getApplicationContext().getContentResolver().query(foo, xxx, xxx);
Also remember that the activity itself is a context (the Activity class is derived from Context), so generally you can use this whenever you need to provide a context ( for example when creating an Intent : new Intent(this, ...)).