Вопрос

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

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

Вот сообщение Eclipse дает мне:

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

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

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

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

Есть ли работа - вокруг? Я собираюсь в запах Android-кода, пытаясь сделать это?

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

Это было полезно?

Решение

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

Другие советы

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

  1. Создать подкласс Application, например, public class MyApp extends Application {...
  2. Установить android:name атрибут вашего <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;

А внутри онкреата:

context = this;

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

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

  1. Подобно тому, что было предложено здесь, создайте класс, который расширяет приложение
  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 напрямую, но до сих пор этот обходной путь был достаточно.

Мое решение:

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

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

  3. В инициализации «Настройка сперматизации специфики» установите соответствующее статическое поле в классе настроек. (Я называю методом «Set Commentsetetate (Key, Value)» в начале OnPreferenCECHANGE ()).

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

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);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top