Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using static methods in Android?

I already made some Apps in Android and noticed that I am often using static methods.

For example I have an Class which extends PreferenceFragment. In this PreferenceFragment I set an onClick event on a Button.

    Button btn = new Button(getActivity().getApplicationContext());
    btn.setText("Save");
    v.addView(btn);
    btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            SettingsActivity.finishActivityWithResultOkey();            
        }
    });

Then I'm calling a static method in my SettingsActivity which finishes this Activity. Is this a good way of doing what I want to do? Or is there a better solution?

like image 818
zFr3eak Avatar asked Mar 19 '23 02:03

zFr3eak


2 Answers

In Android (in memory managed programming languages like Java, more precisely), static methods can lead to "memory leaks" if not used correctly. I've quoted "memory leaks" as they are not the pure definition of memory leaks, like in C++ where you forget to remove some items from memory and lose the reference to them (and thus cannot clear them later on - at least not easily), but more like keeping on to references when you no longer need them and preventing the GC from doing its job in clearing that memory for you. There are a lot of articles on the web that cover this (search for "Android static memory leak") and a lot of other questions on SO that have been asked about this (see [static][Android][memory-leaks] tags), so I won't go into this.

For your particular case, in order to avoid possible memory leaks, you can get the Activity from the Fragment object that your anonymous OnClickListener object is tied to by using MyFragmentClass.this.getActivity(), cast it to, say, SettingsActivity (as is the case here) and call .finishActivityWithResultOkey() on it. It's best that you guard your cast too.

Here's an example of how the code could look like:

btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            final Activity activity = MyFragmentClass.this.getActivity();
            if(activity instanceof SettingsActivity)
               ((SettingsActivity)activity).finishActivityWithResultOkey();
            else
               throw new IllegalStateException("This OnClickListener requires a SettingsActivity to start the fragment containig it"); //helps with debugging
        }
    });

As a note: MyFragmentClass refers to the class of the fragment that you're putting this code in :)

like image 89
lucian.pantelimon Avatar answered Mar 20 '23 15:03

lucian.pantelimon


You can use a Java property known as mirroring. Below I use the property to finish the activity.

 Button btn = new Button(getActivity().getApplicationContext());
    btn.setText("Save");
    v.addView(btn);
    btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            SettingsFragment.this.getActivity().finish();            
        }
    });
like image 22
user2001693 Avatar answered Mar 20 '23 16:03

user2001693