Accedendo SharedPreferences attraverso metodi statici
-
25-09-2019 - |
Domanda
Ho delle informazioni memorizzate come SharedPreferences. Ho bisogno di accedere a tali informazioni da outsite un'attività (in da una classe modello di dominio). Così ho creato un metodo statico in un'attività che uso solo per ottenere le preferenze condivise.
Questo mi sta dando qualche problema, dal momento che a quanto pare non è possibile chiamare il metodo "getSharedPreferences" da un metodo statico.
Ecco l'eclissi messaggio viene avermi dato:
Cannot make a static reference to the non-static method
getSharedPreferences(String, int) from the type ContextWrapper
Ho cercato di aggirare il problema utilizzando un'istanza di attività, in questo modo:
public static SharedPreferences getSharedPreferences () {
Activity act = new Activity();
return act.getSharedPreferences("FILE", 0);
}
Questo codice dà un'eccezione punto zero.
C'è un work-around? Sto andando in un androide-codice-odore, cercando di fare questo?
Grazie in anticipo.
Soluzione
Questo perché, in questo caso, act
è un oggetto che avete appena creato. Bisogna lasciare Android farlo per voi; getSharedPreferences()
è un metodo di Context
, (Activity
, Service
e altre classi estende da Context
). Quindi, dovete fare la vostra scelta:
-
Se il metodo è all'interno di un'attività o altro tipo di contesto:
getApplicationContext().getSharedPreferences("foo", 0);
-
Se il metodo è al di fuori di un'attività o di altro tipo di contesto:
// 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());
Altri suggerimenti
La risposta di Cristian è buono, ma se si vuole essere in grado di accedere alle proprie preferenze condivise da tutto il mondo nel modo giusto potrebbe essere:
- Crea una sottoclasse di
Application
, per esempiopublic class MyApp extends Application {
... - Imposta l'attributo
android:name
del tag<application>
nel AndroidManifest.xml a punto per la nuova classe, per esempioandroid:name="MyApp"
(così la classe è riconosciuta da Android) - Nel metodo onCreate () dell'istanza di applicazione, salvare il contesto (ad esempio
this
) per un campo statico di nomeapp
e creare un metodo statico che restituisce questo campo, ad esempio,getApp()
. È quindi possibile utilizzare questo metodo più tardi per ottenere un contesto dell'applicazione e quindi ottenere le preferenze condivise. : -)
Ho avuto un problema simile e ho risolto semplicemente passando il contesto corrente alla funzione statica:
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);
}
Dal momento che si chiama da fuori di un'attività, dovrete salvare il contesto:
public static Context context;
E dentro OnCreate:
context = this;
Memorizzazione contesto come variabile statica, può causare problemi perché quando la classe viene distrutta quindi sono le variabili statiche. Ciò talvolta accade quando l'applicazione viene interrotto e diventa basso sulla memoria. Basta fare in modo che il contesto è sempre impostato prima di tentare di usarlo anche quando l'impostazione del contesto classe è distrutto in modo casuale.
Ecco un'alternativa migliore per memorizzare le preferenze comuni in campi statici.
- Analogamente a quanto è stato suggerito qui, creare una classe che estende Application
- Fare il costruttore per la classe di prendere Context come parametro.
- Usa il contesto per ottenere le preferenze condivise e memorizzarli in variabili private.
- Crea le variabili pubbliche per restituire i dati recuperati.
es
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;
}
}
Utilizzo nella vostra attività
UserInfo user = new UserInfo(this.getApplicationContext());
String SAVED_USERNAME = user.getSavedUserName();
String SAVED_USERID = user.getSavedUserID();
Ho avuto lo stesso bisogno - alcuni dei miei preferenze devono essere accessibili, spesso, e in modo efficiente. Ho anche immaginare che la lettura e la scrittura di una stringa da SharedPreferences è leggermente più lento di ottenere e impostare una variabile statica (ma probabilmente in misura non significativa). Ho anche appena sorta di abituato ad usare i campi statici, recuperando i valori di preferenza solo all'avvio, e salvandoli su una stretta.
non amavo le mie opzioni per mantenere i riferimenti statici alle SharedPreferences / contesti direttamente, ma finora questa soluzione è stata sufficiente.
La mia soluzione:
-
Creare una classe Impostazioni con tutte le variabili statiche necessari.
-
Quando le inizializza applicazione, recuperare campi SharedPreferences e subito impostare tutti i campi delle impostazioni (che io chiamo un "loadSharedPrefs ()" metodo alla fine del metodo di onCreate di MainActivity).
-
In inizializzazione di preferenceChangeListener del SettingsActivity, impostare il campo statico appropriata nella classe Impostazioni. (Che io chiamo un "setAppropriateSetting (chiave, valore) il" metodo a inizio del SettingsActivity onPreferenceChange ()).
Utilizzare le preferenze statiche, ovunque, ogni volta!
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);
}