0

I want to avoid duplicating code that needs to use methods on Activity (say getActivity().getString()) .

Creating a object that keeps a reference to an Activity does not seem to work (objects are recreated all the time, and any reference to an Activity is null when you need it.)

// This won't work, it seems
public class MyUtils {
    public MyUtils(Activity activity) {
      this.activity = activity;
    }
    public String getSomeStuff() {
       return this.activity.getString(R.string.foo);
    }
}

// In a Fragment created by the activity

MyUtils utils = new MyUtils(getActivity());
myUtils.getSomePref();

So how to you avoid duplicating code ? Is there a "safe" way to factor code that needs an Activity ? Should you put all the code in the Activity itself, and cast it from Fragments ?

Edit : to clarify my issue, I'm especially looking for a way to share code between Fragments, that are displayed as Tabs in an Activity (using a TabsPagerAdapter). They all need to access some structured data that is saved as a couple of preferences. They also need to access this data in an onSharedPreferencesChanged event handler, when the Fragments are not visible. In my experience, whenever I stop and resume the application, navigate between fragments, change the preferences, etc... all my variables to the activity are null.

phtrivier
  • 13,047
  • 6
  • 48
  • 79
  • Why not refreshing the variable each time the activity gets resumed? Fragments support the `onCreate`, `onResume` methods etc. – didierc Nov 21 '14 at 18:59
  • 1
    also, is that really code duplication? – didierc Nov 21 '14 at 19:06
  • Do you have any real-world example besides `getString()`? This is not code duplication really. You'd simply be unnecessarily wrapping the `getActivity().getString()` function with another equally repetitive function. – Jeffrey Mixon Nov 21 '14 at 19:34
  • Well, in my cases, I use a number of SharedPreferences, and I want to wrap the code that gets stome preferences based on soft-coded Strings. So yes, it's to avoid code duplication. – phtrivier Nov 24 '14 at 09:01

2 Answers2

1

An alternative is to give the Activity as a parameter to every utility function. (You can even make them static this way.) Also if you don't need Activity specific functions, use Context instead for more generic methods.

public class MyUtils {
    public static String getSomeStuff(Context a) {
       return a.getString(R.string.foo);
    }

    // more static utility function here
}
kupsef
  • 3,357
  • 1
  • 21
  • 31
  • 2
    In this case (and a lot of others) it would be better to use Context instead of Activity (Activity extends Context). For example, you have no access to an Activity within a Service, but you can use getApplicationContext() to get a Context and use this function there as well. –  Nov 21 '14 at 18:59
  • 1
    @mus65 good point but you could use `ServiceName.this` or `this` since `Service` also extends `Context`. Which would probably be better in most cases than `getApplcationContext()`. Kupsef, if you change that then you get an upvote from me since I was about to give the same answer but with `Context` – codeMagic Nov 21 '14 at 19:02
  • @codeMagic: `Which would probably be better in most cases than getApplcationContext()` source ? – njzk2 Nov 24 '14 at 23:52
  • @njzk2 Start with [this SO post](http://stackoverflow.com/questions/7298731/when-to-call-activity-context-or-application-context/7298955#7298955) and read through the links contained in it – codeMagic Nov 25 '14 at 00:01
  • @njzk2 You're welcome. [This blog post](http://www.doubleencore.com/2013/06/context/) is hidden in a comment in the previous link but certainly worth reading. Probably should have been edited into his answer. – codeMagic Nov 25 '14 at 00:10
0

I usually share my SharedPreferences using a SuperActivity:

public class SuperActivity extends Activity {
    protected SharedPreferences prefs;
    public static final String PREFS_FILE = "PreferencesFile";
    public static final String STRING_VALUE_KEY = "StringVal";

    protected void onResume() {
        super.onResume();
        prefs = this.getSharedPreferences(PREFS_FILE, 0);
    }

    public String getStringValue() {
        prefs.getString("STRING_VALUE_KEY", "")
    }
}

public class SomeActivity extends SuperActivity {
    ....
}

And then you could call:

getActivity().getStringValue();

from anywhere I would think..

Lou Morda
  • 5,078
  • 2
  • 44
  • 49