Доступ к SharedPreferences с помощью статических методов

у меня есть некоторая информация, хранящаяся в SharedPreferences. Мне нужно получить доступ к этой информации из внешнего действия (из класса модели домена). Поэтому я создал статический метод в действии, которое я использую только для получения общих настроек.

это дает мне некоторые проблемы, так как, по-видимому, невозможно вызвать метод "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-код-запах, пытаясь сделать это?

спасибо заранее.

6 ответов


это потому, что в этом случае act - это объект, который вы создаете. Вы должны позволить Android сделать это за вас;getSharedPreferences() метод Context, (Activity, Service и другие классы простирается от Context). Итак, вы должны сделать свой выбор:

  • если метод находится внутри действия или другого контекста:

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

ответ Кристиана хорош, но если вы хотите иметь доступ к вашим общим предпочтениям отовсюду, правильный путь будет:

  1. создать подкласс Application, например,public class MyApp extends Application {...
  2. установить вашего <application> тег в AndroidManifest.xml, чтобы указать на ваш новый класс, например android:name="MyApp" (таким образом, класс распознается Android)
  3. в методе onCreate() экземпляра приложения сохраните контекст (например this) в статическое поле с именем app и создать статический метод, который возвращает это поле, например,getApp(). Затем вы можете использовать этот метод позже, чтобы получить контекст приложения и, следовательно, получить общие настройки. :-)

у меня была аналогичная проблема, и я решил ее, просто передав текущий контекст статической функции:

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;

сохранение контекста в качестве статической переменной может вызвать проблемы, потому что когда класс уничтожается, так и статические переменные. Иногда это происходит, когда приложение прерывается и становится низким память. Просто убедитесь, что контекст всегда задан, прежде чем пытаться его использовать, даже если класс, задающий контекст, случайным образом уничтожен.


вот лучшая альтернатива для хранения ваших общих предпочтений в статических полях.

  1. подобно тому, что было предложено здесь, создайте класс, который расширяет Application
  2. сделайте конструктор для вашего класса контекстом в качестве параметра.
  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();

У меня была такая же потребность - некоторые из моих предпочтений должны быть доступны часто и эффективно. Я также предполагаю, что чтение и запись строки из SharedPreferences немного медленнее, чем получение и установка статической переменной (но, вероятно, в незначительной степени). Я также привык использовать статические поля, получать значения предпочтений только при запуске и сохранять их при закрытии.

Мне не понравились мои варианты сохранения статических ссылок на SharedPreferences / contexts напрямую, но до сих пор этого обходного пути было достаточно.

мое решение:

  1. создание класса настройки с все статические переменные нужно.

  2. когда приложение инициализируется, извлеките поля SharedPreferences и немедленно установите все поля настроек (я вызываю метод "loadSharedPrefs()" в конце метода onCreate MainActivity).

  3. точки останова по инициализация preferenceChangeListener, установите соответствующее статическое поле в классе настроек. (Я вызываю метод "setAppropriateSetting (key, value)" в начале onPreferenceChange () SettingsActivity.)

используйте свои статические настройки где угодно, когда угодно!


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