通过静态方法访问SharedPreferences

MyN*_*ero 31 android static-methods sharedpreferences android-activity

我有一些信息存储为SharedPreferences.我需要从外部的Activity(从域模型类中)访问该信息.所以我在Activity中创建了一个静态方法,我只用它来获取共享首选项.

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

这是eclipse给我的信息:

Cannot make a static reference to the non-static method 
getSharedPreferences(String, int) from the type ContextWrapper
Run Code Online (Sandbox Code Playgroud)

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

public static SharedPreferences getSharedPreferences () {
  Activity act = new Activity();
  return act.getSharedPreferences("FILE", 0);
}
Run Code Online (Sandbox Code Playgroud)

此代码提供null点异常.

有解决方法吗?我试图这样做,我会进入一个android-code气味?

提前致谢.

mre*_*elt 65

Cristian的答案很好,但如果您希望能够从任何地方访问您的共享偏好,那么正确的方法是:

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

  • @MattQuiros:如果是这种情况,那么我的许多应用程序都会在这一行中抛出异常.他们没有.确切地说,应用程序启动时,应用程序#onCreate()被称为*always*. (7认同)
  • 这不是一个好方法.当Android终止进程或手机重启时,静态变量`app`将保持空值,因为不会立即调用`onCreated`. (3认同)
  • ^只要设备处于打开状态并且应用程序**不是**手动启动,如果您在后台重复发出警报,则会导致错误.再说一次,如果你的用例总是涉及手动启动应用程序,那可能无关紧要. (3认同)

Cri*_*ian 36

那是因为在这种情况下,act是您刚刚创建的对象.你必须让Android为你做这件事; getSharedPreferences()是的方法Context,( Activity,Service和其它类从延伸Context).所以,你必须做出选择:

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

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

    // 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());
    
    Run Code Online (Sandbox Code Playgroud)


Dan*_*ray 8

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

public static Context context;
Run Code Online (Sandbox Code Playgroud)

在OnCreate里面:

context = this;
Run Code Online (Sandbox Code Playgroud)

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


小智 6

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

  1. 与这里建议的类似,创建一个扩展 Application 的类
  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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的活动中的使用

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

   String SAVED_USERNAME = user.getSavedUserName();
   String SAVED_USERID = user.getSavedUserID();
Run Code Online (Sandbox Code Playgroud)