How can I use my global variable inside an Adapter class? Android - java

Hi i'm trying to pass a value by using Global Variable. I have created a class file where it is extended to Application and then add it on my Manifest.
public class MyApplication extends Application {}
After that I had created an Adapter Class which is extended to BaseExpandableListAdapter, I've search on how to set and get the global variable i've created and found this
((MyApplication) getActivity().getApplication()).setMy_id(my_id);
and to be able to get the value I use this
Integer my_id = ((MyApplication) getActivity().getApplication()).getMy_id();
In my Fragments, I can use my getMy_id() method but when putting it inside the BaseExpandableListAdapter, I'm having an error in getActivity(). I already tried using this but still it says Cannot resolve method getApplication(), is there any other way to get the value of my global variable.
I'm doing this because I'm trying to use Cursor for my ListView. I wanted to create a Expandable ListView where the data is from my database and my Cursor have a parameter for it's WHERE condition where my data in my global variable will be used.
The reason why I'm using it as a global variable because I use this data in different Fragments where it is not static it changes its value depends on the selected item.
Thank you in advance.

You need to have a constructor in your class that extends BaseExpandableListAdapter. The defined constructor should receive a parameters of Context type. Here is the example -
private Context mContext;
public YourExpandableListAdapter(Context context) {
mContext = context;
Integer my_id = ((MyApplication) context.getApplicationContext()()).getMy_id();
}
Now create an instance like this in your activity -
YourExpandableListAdapter ob = new YourExpandableListAdapter(this);
This should work.

I'm not really sure what you're trying to achieve but whatever it is you're doing seems hacky to me! As per answering your question, getApplication() needs a context, so when you do
((MyApplication) getActivity().getApplication())
You are essentially using the activitiy's(getActivity()) context. And you cannot call getActivity() in an Adapter class. Try passing the context of your activity from the activity to the adapter in your constructor, something like.
MyAdapter myAdapter = new MyAdapter(this); //This line will be in your activity, and this will be the instance of your activity
And your adapter constructor would look something like
public MyAdapter(Context context){
//Use this context to get the application instance, something like
Integer my_id = ((MyApplication) context.getApplication()).getMy_id();
}

For Me, all above didn't work. try this:
((MyApplication) context.getApplicationContext()).getMy_id();

Related

Getting the Activity inside Adapter in Android

I am trying to access the activity on which my Imageview is, so I can use the URL of an Image of type SVG and display it to the user using the GlideToVectorYou library.
GlideToVectorYou.justLoadImage(activity, IMAGE_URI, targetImageView)
But when I try to get access to the activity using R.layout.activityname, a syntax error appears.
this is the code that I'm using
Uri myurl = Uri.parse(match.getFlag());
GlideToVectorYou.justLoadImage(R.layout.item_basketball, myurl, iv_location);
Thank you!
R.layout.item_basketball is just an integer ID for your activity layout - not the activity instance itself. If you want the activity in your adapter you would need to pass it in when you construct the adapter and save it as a class member (example below), or check if your adapter base class already can provide it via getActivity() or getContext() or a similar method.
class MyAdapter(private val activity: Activity) : BaseAdapter() {
fun someMethod() {
// then you can access "activity" in your adapter methods
GlideToVectorYou.justLoadImage(activity, IMAGE_URI, targetImageView)
}
}
and when you create it in your Activity, you would just do something like this
val adapter = MyAdapter(this)
You need a activity reference. R.layout.somethinghere is the layout reference.
On your adapter constructor add a activity parameter and use it inside the adapter.
If you call adapter constructor from an activity, just pass "this" as parameter. If call from a fragment, use "requireActivity" (if using kotlin) or analogous method (getActivity, for example) if using Java

Android - Hold Activity reference in application-level non-Activity class

I have an application class and it holds a reference of MyAdapter class:
public class MyApplication extends Application {
......
private static MyAdapter sMyAdapter;
public static MyAdapter getMyAdapter() {
if (sMyAdapter == null) {
sMyAdapter = new MyAdapter(this);
MyApplication.setMyAdapter(sMyAdapter);
}
return sMyAdapter;
}
public static void setMyAdapter(MyAdapter myAdapter) {
sMyAdapter = myAdapter;
}
......
}
MyAdapter class is a customized android adapter class, and the application Context is passed to the Adapter. The application holds a reference of it because it may be used anytime till the application is still running.
The problem is that now I need an Activity Context in the Adapter to start another Activity when some button is clicked because if I use application Context I need to add a Intent flag FLAG_ACTIVITY_NEW_TASK which I don't want to because that way the new Activity being started will be running in a new task. I tried a lot with changing launch mode and taskAffinity but either new issues came up or the Activity will be running in a new task.
So I am thinking to hold an Activity reference which shows the button in the Adapter class, and to avoid memory leak, I came up with the following:
public class MyActivity extends Activity {
......
#override
public void onResume() {
......
MyApplication.getMyAdapter().setActivity(this);
......
}
......
#override
public void onDestroy() {
......
MyApplication.getMyAdapter().setActivity(null);
......
}
}
Then in the Adapter class I will use the Activity reference to start another Activity. I tested and this worked fine but the question is would this avoid memory leak and is this a proper way to hold the Activity reference when onResume and release it when onDestroy? Is there any other decent way to achieve my purpose? Thanks.
would this avoid memory leak
Not really. You MyApplication object will still keep a reference to your adapter with all it's 'contents' (further references).
Yes, you've got rid of keeping the destroyed Activity around, and you might feel it's okay to keep the adapter because you're 'going to need it again anyways', still this whole construct is a horrible code smell and will with certainty introduce new memory leaks and other problems as you develop this further.
Logically, this adapter is part of an Activity, and as the Activity 'dies', so should the adapter.
I'm sure there's a reason why you felt you needed that adapter on your application, so I'd post another question asking 'how can I achieve soandso without my application knowing of my adapter'.

android get context of fragment in activity

I want to get the context or instance of fragment in a activity.I tried following codeļ¼š
In fragment:
public static XXFragment instance;
In the onCreate():
instance = this;
In activity:
Context context = XXFrangment.instance;
But it has NullPointerException error.Because I haven't invoked onCreate() of fragment.So how can I do to get the context or instance of Fragment?Hope somebody could help me!
I think there is some error in your way of thinking about Context :-)
First of all, Fragment does not have a Context until added to an Activity. After it is added, the Activity itself is it's Context, so there is no need to extract it from the Fragment. Just use this in Activity code :-)
As a side note, avoid static fields holding complex objects such as Fragments and Activities. In a real, production environment you will never do this, as it leads to so called memory leaks, a big problem in software.
It's good practice to use static method for fragment initializing. Implement this method in your fragment class:
public static YourFragment newInstance() {
Bundle args = new Bundle();
YourFragment fragment = new YourFragment();
fragment.setArguments(args);
return fragment;
}
As you can see, you are able to add parameters in a newInstance() method. These parameters are usually used for adding them as arguments of the fragment.

Static Context from Activity.onStart()

I am trying to generate a notification from a class, Utilities.java, outside of the subclass of Context. I've thought about providing a SingletonContext class and have looked at posts ike this. I'd like to be able to return != null Context object since the notification can be generated at any given time because it is generated from a messageReceived() callback.
What are there downsides to doing something like this:
public static Context c;
public class MainActivity extends Activity{
#Override
public void onStart()
super.onStart()
c = this.getApplicationContext();
}
//other method somewhere outside this class
public Context getContext(){
return MainActivity.c
}
I don't think it would be any different than putting this on the onCreate(), however, it guarantees that the context is up to date when the activity starts.
The Context keeps a reference to this activity in memory, which you might not want. Perhaps use
this.getApplicationContext();
instead. This will still let you do file IO and most other things a context requires. Without a specific reference to this activity.
Maybe you should overwrite the onResume Method.
If you open a new activity, and switch back, the onStart method will not getting invoked.
Android Lifecycle: doc
BTW: I read about problems with ApplicationContext using a dialog or toast, so if you use the context to create on of these you should use your Activity as context.

Context having reference to class in android

Hi i am trying to understand the use of context though i couldn't. Following is a program using context. My question is what is the significance of " context = class.this " ?
class public VcardActivity extends Activity
{
String Vcard = "vcard";
Context context;
}
public void onCreate ( Bundle bn )
{
super.onCreate(bn);
setContentView(R.layout.main);
context = VcardActivity.this;
}
Your current code doesn't show the use of context. It shows that the Activity is a context.
TextView someText=new TextView(context);
This code of mine shows, I am passing a context into the constructor of a TextView in order to make this object. The reason is, this object needs to know the information, state of the current context, and this is the reason why many views, classes, helpers needs a context.
context = VcardActivity.this;
in your code you are having your activity object to assign to the Context context. This works because Activity class inherits from Context and many classes needs a Context to create it.
In your case, the field context is not necessary at all. It rather is used as a shortcut to VcardActivity.this here. You could remove it without any problems and use VcardActivity.this or even only this where you used to use context.
You don't need to create a separate Context variable inside of an Activity. You use Context for certain objects/methods that need to know what is starting them. Activity already has a Context so you don't need to create it. If you need to use Context within an Activity, say when creating an Intent you can just use ActivityName.this or here VcardActivity
See this SO answer for a good explanation of using which kind of Context when.
Context Docs

Categories

Resources