J'ai des informations stockées en tant que SharedPreferences. J'ai besoin d'accéder à ces informations à partir d'une activité externe (à partir d'une classe de modèle de domaine). J'ai donc créé une méthode statique dans une activité que je n'utilise que pour obtenir les préférences partagées.
Cela me pose quelques problèmes, car il n'est apparemment pas possible d'appeler la méthode "getSharedPreferences" à partir d'une méthode statique.
Voici le message que Eclipse me donne:
Cannot make a static reference to the non-static method
getSharedPreferences(String, int) from the type ContextWrapper
J'ai essayé de contourner ce problème en utilisant une instance Activity, comme ceci:
public static SharedPreferences getSharedPreferences () {
Activity act = new Activity();
return act.getSharedPreferences("FILE", 0);
}
Ce code donne une exception de point nul.
Y at-il un travail autour? Est-ce que j'entre dans une odeur de code Android en essayant de le faire?
Merci d'avance.
En effet, dans ce cas, act
est un objet que vous venez de créer. Vous devez laisser Android faire cela pour vous. getSharedPreferences()
est une méthode de Context
, (Activity
, Service
et d'autres classes s'étend de Context
). Alors, vous devez faire votre choix:
Si la méthode est à l'intérieur d'une activité ou d'un autre type de contexte:
getApplicationContext().getSharedPreferences("foo", 0);
Si la méthode est en dehors d'une activité ou d'un autre type de contexte:
// 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());
La réponse de Cristian est bonne, mais si vous voulez pouvoir accéder à vos préférences partagées de partout, la bonne façon serait:
Application
, par exemple. public class MyApp extends Application {
...Android:name
de votre balise <application>
dans le fichier AndroidManifest.xml pour qu'il pointe vers votre nouvelle classe, par exemple. Android:name="MyApp"
(donc la classe est reconnue par Android)this
) dans un champ statique nommé app
et créez une méthode statique qui renvoie ce champ, par exemple. getApp()
. Vous pourrez ensuite utiliser cette méthode ultérieurement pour obtenir un contexte de votre application et donc obtenir vos préférences partagées. :-)J'ai eu un problème similaire et je l'ai résolu en passant simplement le contexte actuel à la fonction statique:
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);
}
Comme vous appelez de l'extérieur d'une activité, vous devez enregistrer le contexte:
public static Context context;
Et à l'intérieur de OnCreate:
context = this;
Stocker le contexte en tant que variable statique peut poser des problèmes car lorsque la classe est détruite, les variables statiques le sont également. Cela se produit parfois lorsque l'application est interrompue et manque de mémoire. Assurez-vous simplement que le contexte est toujours défini avant d'essayer de l'utiliser, même lorsque la classe définissant le contexte est détruite de manière aléatoire.
Voici une meilleure alternative au stockage de vos préférences partagées dans des champs statiques.
par exemple
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;
}
}
utilisation dans votre activité
UserInfo user = new UserInfo(this.getApplicationContext());
String SAVED_USERNAME = user.getSavedUserName();
String SAVED_USERID = user.getSavedUserID();
J'avais le même besoin - certaines de mes préférences doivent être consultées souvent et efficacement. J'imagine également que la lecture et l'écriture d'une chaîne à partir de SharedPreferences est légèrement plus lente que l'obtention et la définition d'une variable statique (mais probablement à un degré insignifiant). Je me suis aussi habitué à utiliser des champs statiques, à ne récupérer les valeurs de préférence qu'au démarrage et à les enregistrer à la fermeture.
Je n'ai pas aimé mes options pour conserver directement les références statiques aux SharedPreferences/contextes, mais cette solution de contournement a jusqu'à présent suffi.
Créez une classe de paramètres avec toutes les variables statiques dont vous avez besoin.
Lorsque l'application s'initialise, récupérez les champs SharedPreferences et définissez immédiatement tous les champs Settings (j'appelle une méthode "loadSharedPrefs ()" à la fin de la méthode onCreate de MainActivity).
Dans l'initialisation de preferenceChangeListener de SettingsActivity, définissez le champ statique approprié dans la classe Settings. (J'appelle une méthode "setAppropriateSetting (clé, valeur)" au début de la méthode onPreferenceChange () de SettingsActivity.
Utilisez vos préférences statiques où, quand!
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);
}