Accessing SharedPreferences through static methods

2019-01-03 09:31发布

I have some information stored as SharedPreferences. I need to access that information from outsite an Activity (in from a domain model class). So I created a static method in an Activity which I only use to get the shared preferences.

This is giving me some problems, since apparently it is not possible to call the method "getSharedPreferences" from a static method.

Here's the message eclipse is giving me:

Cannot make a static reference to the non-static method 
getSharedPreferences(String, int) from the type ContextWrapper

I tried to work around this by using an Activity instance, like this:

public static SharedPreferences getSharedPreferences () {
  Activity act = new Activity();
  return act.getSharedPreferences("FILE", 0);
}

This code gives a null point exception.

Is there a work-around? Am I going into an android-code-smell by trying to do this?

Thanks in advance.

6条回答
男人必须洒脱
2楼-- · 2019-01-03 09:59

Cristian's answer is good, but if you want to be able to access your shared preferences from everywhere the right way would be:

  1. Create a subclass of Application, e.g. public class MyApp extends Application {...
  2. Set the android:name attribute of your <application> tag in the AndroidManifest.xml to point to your new class, e.g. android:name="MyApp" (so the class is recognized by Android)
  3. In the onCreate() method of your app instance, save your context (e.g. this) to a static field named app and create a static method that returns this field, e.g. getApp(). You then can use this method later to get a context of your application and therefore get your shared preferences. :-)
查看更多
地球回转人心会变
3楼-- · 2019-01-03 10:01

I had a similar problem and I solved it by simply passing the current context to the static function:

public static void LoadData(Context context)
{
    SharedPreferences SaveData = context.getSharedPreferences(FILENAME, MODE_PRIVATE);
    Variable = SaveData.getInt("Variable", 0);
    Variable1 = SaveData.getInt("Variable1", 0);
    Variable2 = SaveData.getInt("Variable2", 0);
}

Since you are calling from outside of an activity, you'll need to save the context:

public static Context context;

And inside OnCreate:

context = this;

Storing the context as a static variable, can cause problems because when the class is destroyed so are the static variables. This sometimes happens when the app is interrupted and becomes low on memory. Just make sure that the context is always set before you attempt to use it even when the class setting the context is randomly destroyed.

查看更多
姐就是有狂的资本
4楼-- · 2019-01-03 10:15
public static String getPreferenceValue(Context context) {
    SharedPreferences sharedPreferences = 
        PreferenceManager.getDefaultSharedPreferences(context);
    String key = context.getString(R.string.pref_key);
    String defaultVal = context.getString(R.string.pref_default);
    return sharedPreferences.getString(key,defaulVal);
}
查看更多
Anthone
5楼-- · 2019-01-03 10:19

I had the same need - some of my preferences need to be accessed often, and efficiently. I also imagine that reading and writing a string from SharedPreferences is slightly slower than getting and setting a static variable (but likely to an insignificant degree). I also just kind of got used to using static fields, retrieving Preference values only at startup, and saving them on close.

I didn't love my options for keeping static references to the SharedPreferences/contexts directly, but so far this workaround has sufficed.

My solution:

  1. Create a Settings class with all the static variables you need.

  2. When the application initializes, retrieve SharedPreferences fields and immediately set all Settings fields (I call a "loadSharedPrefs()" method at the end of MainActivity's onCreate method).

  3. In the SettingsActivity's preferenceChangeListener's initialization, set the appropriate static field in the Settings class. (I call a "setAppropriateSetting(key, value)" method at the beginning of SettingsActivity's onPreferenceChange()).

Use your static preferences wherever, whenever!

查看更多
孤傲高冷的网名
6楼-- · 2019-01-03 10:20

That's because in this case, act is an object that you just create. You have to let Android do that for you; getSharedPreferences() is a method of Context, (Activity, Service and other classes extends from Context). So, you have to make your choice:

  • If the method is inside an activity or other kind of context:

    getApplicationContext().getSharedPreferences("foo", 0);
    
  • If the method is outside an activity or other kind of context:

    // you have to pass the context to it. In your case:
    // this is inside a public class
    public static SharedPreferences getSharedPreferences (Context ctxt) {
       return ctxt.getSharedPreferences("FILE", 0);
    }
    
    // and, this is in your activity
    YourClass.this.getSharedPreferences(YourClass.this.getApplicationContext());
    
查看更多
乱世女痞
7楼-- · 2019-01-03 10:20

Here's a better alternative to storing your shared preferences in static fields.

  1. Similar to what has been suggested here, create a class that extends Application
  2. Make the constructor for your class take Context as a parameter.
  3. Use your context to get shared preferences and store them in private variables.
  4. Create public variables to return the retrieved data.

e.g

public class UserInfo extends Application{
    private String SAVED_USERID;
    private String SAVED_USERNAME;

    public UserInfo(Context context) {
        SharedPreferences prefs = context.getSharedPreferences(FILE, MODE_PRIVATE);
        SAVED_USERNAME = prefs.getString("UserName", null);
        SAVED_USERID = prefs.getString("UserID", null);
    }

    public String getSavedUserName() {
        return SAVED_USERNAME;
    }

    public String getSavedUserID() {
         return SAVED_USERID;
    }
}

usage in your activity

   UserInfo user = new UserInfo(this.getApplicationContext());

   String SAVED_USERNAME = user.getSavedUserName();
   String SAVED_USERID = user.getSavedUserID();
查看更多
登录 后发表回答