Question

J'ai des informations stockées sous forme SharedPreferences. J'ai besoin d'accéder à cette information de outsite une activité (à 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 donne des problèmes, puisque apparemment il est impossible d'appeler la méthode « getSharedPreferences » à partir d'une méthode statique.

Voici l'éclipse de message 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 d'activité, comme ceci:

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

Ce code donne une exception point zéro.

Y at-il un travail autour? Est-ce que je vais dans un androïde code-odeur en essayant de le faire?

Merci d'avance.

Était-ce utile?

La solution

En effet, dans ce cas, act est un objet que vous venez de créer. Vous devez laisser Android faire pour vous; getSharedPreferences() est une méthode de Context, (Activity, Service et d'autres classes étend depuis Context). Donc, vous devez faire votre choix:

  • Si la méthode est à l'intérieur d'une activité ou un autre type de contexte:

    getApplicationContext().getSharedPreferences("foo", 0);
    
  • Si la méthode est en dehors d'une activité ou 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());
    

Autres conseils

La réponse de Cristian est bon, mais si vous voulez être en mesure d'accéder à vos préférences partagées de partout la bonne façon serait:

  1. Créer une sous-classe de Application , par exemple public class MyApp extends Application { ...
  2. Définissez l'attribut android:name de votre tag <application> dans le AndroidManifest.xml pour pointer vers votre nouvelle classe, par exemple android:name="MyApp" (si la classe est reconnue par Android)
  3. Dans la méthode de votre instance d'application, enregistrez votre contexte (par exemple this) à un champ statique nommé app et créer une méthode statique onCreate () qui retourne ce domaine, par exemple getApp(). Vous pouvez ensuite utiliser cette méthode pour obtenir plus tard 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 de 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);
}

Puisque vous appelez de l'extérieur d'une activité, vous devez enregistrer le contexte:

public static Context context;

Et à l'intérieur OnCreate:

context = this;

Stockage du contexte comme une variable statique, peut causer des problèmes parce que quand la classe est détruite sont donc les variables statiques. Cela arrive parfois lorsque l'application est interrompue et devient faible sur la mémoire. Assurez-vous que le contexte est toujours défini avant de tenter de l'utiliser même lorsque la classe mise en contexte est détruit au hasard.

Voici une meilleure alternative à stocker vos préférences partagées dans les champs statiques.

  1. Similaire à ce qui a été suggéré ici, créer une classe qui étend l'application
  2. Faites le constructeur de votre classe Contexte prendre comme paramètre.
  3. Utilisez votre contexte pour obtenir les préférences partagées et les stocker dans des variables privées.
  4. Créer des variables publiques pour retourner les données récupérées.

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'ai eu le même besoin - certains de mes préférences doivent être lues souvent et efficacement. J'imagine aussi que la lecture et l'écriture d'une chaîne de SharedPreferences est légèrement plus lent que d'obtenir et de définir une variable statique (mais probablement à un degré insignifiant). Je viens aussi de genre me suis habitué à l'aide de champs statiques, la récupération des valeurs de préférence seulement au démarrage, et de les enregistrer à la fermeture.

Je n'ai pas aimé mes options pour garder les références statiques aux SharedPreferences / contextes directement, mais jusqu'à présent, cette solution de contournement a suffi.

Ma solution:

  1. Créer une classe avec tous les paramètres variables statiques dont vous avez besoin.

  2. Lorsque l'application initialise, récupérer des champs de SharedPreferences et immédiatement mis tous les champs Paramètres (je l'appelle une méthode "loadSharedPrefs ()" à la fin de la méthode onCreate de MainActivity).

  3. Dans l'initialisation de preferenceChangeListener du SettingsActivity, définissez le champ statique approprié dans la classe Paramètres. (Je l'appelle une méthode "setAppropriateSetting (clé, valeur)" au début de onPreferenceChange () de SettingsActivity).

Utilisez vos préférences statiques où, à chaque fois!

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);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top