Доступ к SharedPreferences через статические методы - PullRequest
31 голосов
/ 27 сентября 2010

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

Это доставляет мне некоторые проблемы, так как, по-видимому, невозможно вызвать метод "getSharedPreferences" из статического метода.

Вот сообщение, которое дает мне затмение:*

Я попытался обойти это, используя экземпляр Activity, например:

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

Этот код дает исключение нулевой точки.

Есть ли обходной путь?Я пытаюсь сделать это с запахом кода Android?

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

Ответы [ 6 ]

65 голосов
/ 27 сентября 2010

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

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

Это потому, что в этом случае 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());
    
8 голосов
/ 16 июля 2013

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

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;

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

4 голосов
/ 30 августа 2015

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

  1. Аналогично тому, что было предложено здесь, создайте класс, расширяющий Application
  2. Заставьте конструктор вашего класса принимать Context в качестве параметра.
  3. Используйте ваш контекст, чтобы получить общие настройки и сохранить их в приватных переменных.
  4. Создание открытых переменных для возврата полученных данных.

* 1013 например *

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();
2 голосов
/ 09 мая 2016

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

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

Мое решение:

  1. Создайте класс Settings со всеми необходимыми статическими переменными.

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

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

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

0 голосов
/ 28 июня 2017
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);
}
...