Acceso SharedPreferences a través de métodos estáticos
-
25-09-2019 - |
Pregunta
Me tiene alguna información almacenada como SharedPreferences. Necesito acceso a esa información de desayunar una actividad (en una clase de modelo de dominio). Así que creé un método estático en una actividad que sólo utilizo para obtener las preferencias compartidas.
Esto me está dando algunos problemas, ya que al parecer no es posible llamar al método "getSharedPreferences" de un método estático.
Aquí está el eclipse mensaje se produce:
Cannot make a static reference to the non-static method
getSharedPreferences(String, int) from the type ContextWrapper
He intentado solucionar este problema utilizando una instancia de actividad, así:
public static SharedPreferences getSharedPreferences () {
Activity act = new Activity();
return act.getSharedPreferences("FILE", 0);
}
Este código da una excepción de punto nulo.
¿Hay una solución alternativa? ¿Voy a un androide-código-olor al tratar de hacer esto?
Gracias de antemano.
Solución
Eso es porque en este caso, act
es un objeto que acaba de crear. Hay que dejar que Android hacer eso por usted; getSharedPreferences()
es un método de Context
, (Activity
, Service
y otras clases se extiende desde Context
). Por lo tanto, usted tiene que hacer su elección:
-
Si el método está dentro de una actividad o de otro tipo de contexto:
getApplicationContext().getSharedPreferences("foo", 0);
-
Si el método se encuentra fuera de una actividad o de otro tipo de contexto:
// 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());
Otros consejos
La respuesta de Cristian es buena, pero si usted quiere ser capaz de acceder a sus preferencias compartidas por todas partes de la manera correcta sería:
- Crea una subclase de
Application
, por ejemplopublic class MyApp extends Application {
... - Establecer el atributo de la etiqueta
android:name
<application>
en el AndroidManifest.xml a punto a su nueva clase, por ejemplo,android:name="MyApp"
(por lo que la clase es reconocida por Android) - En el método onCreate () de la instancia de aplicación, guarde su contexto (por ejemplo
this
) a un campo estático llamadoapp
y crear un método estático que devuelve este campo, por ejemplo,getApp()
. A continuación, puede utilizar este método más adelante para obtener un contexto de su aplicación y, por tanto, obtener sus preferencias compartidas. : -)
He tenido un problema similar y lo solucioné simplemente pasando el contexto actual de la función estática:
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);
}
Desde que está llamando desde fuera de una actividad, que tendrá que guardar el contexto:
public static Context context;
Y en el interior OnCreate:
context = this;
Almacenamiento del contexto como una variable estática, puede causar problemas porque cuando la clase se destruye también lo son las variables estáticas. Esto ocurre a veces cuando la aplicación se interrumpe y se vuelve poca memoria. Sólo asegúrese de que el contexto siempre se establece antes de intentar utilizar incluso cuando la clase establecer el contexto se destruye al azar.
Aquí hay una mejor alternativa a tener sus preferencias compartidas en los campos estáticos.
- Similar a lo que se ha sugerido aquí, crear una clase que se extiende Aplicación
- Hacer el constructor de la clase toma Contexto como parámetro.
- Use su contexto para obtener preferencias compartidas y almacenarlos en variables privadas.
- Crear variables públicas para devolver los datos recuperados.
por ejemplo
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;
}
}
el uso en su actividad
UserInfo user = new UserInfo(this.getApplicationContext());
String SAVED_USERNAME = user.getSavedUserName();
String SAVED_USERID = user.getSavedUserID();
Yo tenía la misma necesidad - algunos de mis preferencias necesitan ser visitada a menudo, y de manera eficiente. También imagino que la lectura y escritura de una cadena de SharedPreferences es ligeramente más lento que obtener y establecer una variable estática (pero probablemente a un grado insignificante). Asimismo, sólo tipo de se acostumbró a usar los campos estáticos, recuperar valores de preferencia solamente en el inicio, y guardarlos en una estrecha.
no me encanta mis opciones para mantener las referencias estáticas a las SharedPreferences / contextos directamente, pero hasta ahora esta solución ha sido suficiente.
Mi solución:
-
Crea una clase de ajustes con todas las variables estáticas que necesita.
-
Cuando se inicie la aplicación, recuperar campos SharedPreferences e inmediatamente todos los campos de configuración (que yo llamo un "loadSharedPrefs ()" método al final del método onCreate de MainActivity).
-
En la inicialización de preferenceChangeListener del SettingsActivity, establezca el campo estático apropiado en la clase de configuración. (Que yo llamo un "setAppropriateSetting (clave, valor)" método al principio de onPreferenceChange de SettingsActivity ()).
Utilice sus preferencias estáticas donde quiera, siempre que sea!
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);
}