web-dev-qa-db-fra.com

Accéder aux SharedPreferences via des méthodes statiques

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.

28
MyNameIsZero

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

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:

  1. Créez une sous-classe de Application , par exemple. public class MyApp extends Application {...
  2. Définissez l'attribut 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)
  3. Dans la méthode onCreate () de votre instance d'application, enregistrez votre contexte (par exemple, 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. :-)
64
mreichelt

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.

7
Dan Bray

Voici une meilleure alternative au stockage de vos préférences partagées dans des champs statiques.

  1. Semblable à ce qui a été suggéré ici, créez une classe qui étend Application
  2. Faites en sorte que le constructeur de votre classe prenne Context comme paramètre.
  3. Utilisez votre contexte pour obtenir des préférences partagées et les stocker dans des variables privées.
  4. Créez des variables publiques pour renvoyer les données extraites.

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

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.

Ma solution:

  1. Créez une classe de paramètres avec toutes les variables statiques dont vous avez besoin.

  2. 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).

  3. 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!

2
Ed Cooper
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);
}
0
Eric Smith