Подтвердить что ты не робот

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

У меня есть информация, хранящаяся как SharedPreferences. Мне нужно получить доступ к этой информации из Outsite 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-код-запах, пытаясь сделать это?

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

4b9b3361

Ответ 1

Это потому, что в этом случае 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());
    

Ответ 2

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

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

Ответ 3

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

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

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

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

например

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

Ответ 5

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

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

Мое решение:

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

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

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

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

Ответ 6

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