34

我有一些信息存储为 SharedPreferences。我需要从 Activity 外部访问该信息(从域模型类中)。因此,我在 Activity 中创建了一个静态方法,仅用于获取共享首选项。

这给了我一些问题,因为显然不可能从静态方法调用方法“getSharedPreferences”。

这是eclipse给我的信息:

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

我试图通过使用 Activity 实例来解决这个问题,如下所示:

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

此代码给出了一个空点异常。

有解决办法吗?我是否会通过尝试执行此操作进入 android-code-smell ?

提前致谢。

4

6 回答 6

67

克里斯蒂安的回答很好,但如果您希望能够从任何地方访问您的共享偏好,正确的方法是:

  1. 创建一个子类Application,例如public class MyApp extends Application {...
  2. 在 AndroidManifest.xml 中设置标签的android:name属性<application>以指向您的新类,例如android:name="MyApp"(以便 Android 识别该类)
  3. 在您的应用实例的 onCreate() 方法中,将您的上下文(例如this)保存到名为的静态字段app并创建一个返回该字段的静态方法,例如getApp()。然后,您可以稍后使用此方法来获取应用程序的上下文,从而获取您的共享偏好。:-)
于 2010-09-27T17:14:29.197 回答
36

这是因为在这种情况下,act是您刚刚创建的对象。你必须让 Android 为你做这件事;getSharedPreferences()是, Context(和其他类从) 扩展而来的方法。因此,您必须做出选择:ActivityServiceContext

  • 如果方法在活动或其他类型的上下文中:

    getApplicationContext().getSharedPreferences("foo", 0);
    
  • 如果该方法在活动或其他类型的上下文之外:

    // 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());
    
于 2010-09-27T17:08:28.910 回答
10

我有一个类似的问题,我通过简单地将当前上下文传递给静态函数来解决它:

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);
}

由于您是从活动外部调用的,因此您需要保存上下文:

public static Context context;

在 OnCreate 内部:

context = this;

将上下文存储为静态变量可能会导致问题,因为当类被销毁时,静态变量也会被销毁。当应用程序中断并且内存不足时,有时会发生这种情况。只需确保在尝试使用上下文之前始终设置上下文,即使设置上下文的类被随机销毁。

于 2013-07-16T04:45:22.607 回答
8

这是将共享首选项存储在静态字段中的更好选择。

  1. 与此处建议的类似,创建一个扩展应用程序的类
  2. 使您的类的构造函数将 Context 作为参数。
  3. 使用您的上下文获取共享偏好并将它们存储在私有变量中。
  4. 创建公共变量以返回检索到的数据。

例如

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;
    }
}

在您的活动中使用

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

   String SAVED_USERNAME = user.getSavedUserName();
   String SAVED_USERID = user.getSavedUserID();
于 2015-08-30T05:25:20.797 回答
2

我也有同样的需求——我的一些偏好需要经常有效地访问。我还想象从 SharedPreferences 读取和写入字符串比获取和设置静态变量稍慢(但可能微不足道)。我也有点习惯于使用静态字段,仅在启动时检索 Preference 值,并在关闭时保存它们。

我不喜欢直接保留对 SharedPreferences/contexts 的静态引用的选项,但到目前为止,这种解决方法已经足够了。

我的解决方案:

  1. 使用您需要的所有静态变量创建一个设置类。

  2. 当应用程序初始化时,检索 SharedPreferences 字段并立即设置所有 Settings 字段(我在 MainActivity 的 onCreate 方法的末尾调用了“loadSharedPrefs()”方法)。

  3. 在SettingsActivity的preferenceChangeListener的初始化中,在Settings类中设置相应的静态字段。(我在 SettingsActivity 的 onPreferenceChange() 开头调用了“setAppropriateSetting(key, value)”方法)。

随时随地使用您的静态偏好!

于 2016-05-08T21:39:02.523 回答
0
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);
}
于 2017-06-28T16:16:10.103 回答