Accediendo a SharedPreferences a través de métodos estáticos

Tengo cierta información almacenada como SharedPreferences. Necesito acceder a esa información desde fuera de una Actividad (desde una clase de modelo de dominio). Así que creé un método estático en una actividad que solo uso para obtener las preferencias compartidas.

Esto me está dando algunos problemas, ya que aparentemente no es posible llamar al método “getSharedPreferences” desde un método estático.

Este es el mensaje que el eclipse me está dando:

Cannot make a static reference to the non-static method getSharedPreferences(String, int) from the type ContextWrapper 

Traté de solucionar esto utilizando una instancia de Activity, como esta:

 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 entrar en un olor a código Android tratando de hacer esto?

Gracias por adelantado.

Eso es porque en este caso, act es un objeto que acaba de crear. Tienes que dejar que Android lo haga por ti; getSharedPreferences() es un método de Context , ( Activity , Service y otras clases se extiende desde el Context ). Entonces, debes hacer tu elección:

  • Si el método está dentro de una actividad u otro tipo de contexto:

     getApplicationContext().getSharedPreferences("foo", 0); 
  • Si el método está fuera de una actividad u 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()); 

La respuesta de Cristian es buena, pero si quieres poder acceder a tus preferencias compartidas desde cualquier lugar, la forma correcta sería:

  1. Cree una subclase de Application , p. Ej., public class MyApp extends Application {
  2. Establezca el atributo android:name de su etiqueta en el AndroidManifest.xml para que apunte a su nueva clase, por ejemplo, android:name="MyApp" (para que la clase sea reconocida por Android)
  3. En el método onCreate () de la instancia de su aplicación, guarde su contexto (por ejemplo, this ) en un campo estático llamado app y cree un método estático que devuelva este campo, por ejemplo, getApp() . Luego puede usar este método más adelante para obtener un contexto de su aplicación y, por lo tanto, obtener sus preferencias compartidas. 🙂

Tuve un problema similar y lo resolví simplemente pasando el contexto actual a 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); } 

Como llama desde fuera de una actividad, deberá guardar el contexto:

 public static Context context; 

Y dentro de OnCreate:

 context = this; 

Almacenar el contexto como una variable estática puede causar problemas porque cuando se destruye la clase también lo son las variables estáticas. Esto sucede a veces cuando la aplicación se interrumpe y queda poca memoria. Solo asegúrese de que el contexto esté siempre configurado antes de intentar usarlo, incluso cuando la clase que configura el contexto se destruya aleatoriamente.

Aquí hay una mejor alternativa para almacenar sus preferencias compartidas en campos estáticos.

  1. Similar a lo que se ha sugerido aquí, crea una clase que extienda la aplicación
  2. Haz que el constructor de tu clase tome Contexto como parámetro.
  3. Use su contexto para obtener preferencias compartidas y almacenarlas en variables privadas.
  4. Crea variables públicas para devolver los datos recuperados.

p.ej

 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; } } 

uso en tu actividad

  UserInfo user = new UserInfo(this.getApplicationContext()); String SAVED_USERNAME = user.getSavedUserName(); String SAVED_USERID = user.getSavedUserID(); 

Tenía la misma necesidad: algunas de mis preferencias deben accederse con frecuencia y de manera eficiente. También me imagino que leer y escribir una cadena de SharedPreferences es un poco más lento que obtener y establecer una variable estática (pero probablemente en un grado insignificante). También me acostumbré a usar campos estáticos, recuperar valores de Preferencia solo al inicio y guardarlos al cerrar.

No me encantaron mis opciones de mantener referencias estáticas a SharedPreferences / contexts directamente, pero hasta ahora esta solución ha sido suficiente.

Mi solución:

  1. Cree una clase de Configuraciones con todas las variables estáticas que necesita.

  2. Cuando la aplicación se inicializa, recupera los campos SharedPreferences e inmediatamente establece todos los campos de Configuración (llamo a un método “loadSharedPrefs ()” al final del método onCreate de MainActivity).

  3. En la inicialización de SettingsActivityChangeListener, establezca el campo estático apropiado en la clase de Configuraciones. (Llamo a un método “setAppropriateSetting (key, value)” al comienzo de SettingsActivity onPreferenceChange ()).

¡Usa tus preferencias estáticas donde sea y cuando 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); } 
Intereting Posts