Cómo usar valores de Preference guardados Parte de Android Jetpack.
En este documento, se describe cómo almacenar y usar los valores Preference
que guarda la biblioteca de Preference.
Almacenamiento de datos de Preference
En esta sección, se describe cómo un objeto Preference
puede persistir datos.
SharedPreferences
De forma predeterminada, un objeto Preference
usa SharedPreferences
para guardar los valores. La API de SharedPreferences
admite la lectura y escritura de pares clave-valor simples de un archivo que se guarda en las sesiones de la aplicación. La biblioteca de Preference usa una instancia privada de SharedPreferences
para que solo tu aplicación pueda acceder a ella.
A modo de ejemplo, supongamos el siguiente objeto SwitchPreferenceCompat
:
<SwitchPreferenceCompat app:key="notifications" app:title="Enable message notifications"/>
Cuando un usuario activa este interruptor, el archivo SharedPreferences
se actualiza con un par clave-valor de "notifications" : "true"
. La clave que se usa es la misma que la clave configurada para Preference
.
Para obtener más información sobre la API de SharedPreferences
, consulta Cómo guardar datos de pares clave-valor.
Para obtener información sobre las diferentes maneras de almacenar datos en Android, consulta Descripción general del almacenamiento de datos y archivos.
PreferenceDataStore
Aunque la biblioteca de Preference conserva datos con SharedPreferences
de forma predeterminada, SharedPreferences
no siempre es una solución ideal. Por ejemplo, si tu aplicación requiere el acceso de un usuario, es posible que quieras conservar la configuración de la aplicación en la nube para que esta se refleje en otros dispositivos y plataformas. Del mismo modo, si tu aplicación tiene opciones de configuración específicas del dispositivo, cada usuario del dispositivo tiene configuraciones individuales, por lo que SharedPreferences
no es una solución ideal.
Un objeto PreferenceDataStore
te permite usar un backend de almacenamiento personalizado para conservar valores de Preference
. Para obtener más información, consulta Usa un almacén de datos personalizado.
Cómo leer valores de Preference
Para recuperar el objeto SharedPreferences
que se usa, llama a PreferenceManager.getDefaultSharedPreferences()
.
Si bien este método funciona desde cualquier parte de tu aplicación, te recomendamos que la dividas en capas. Para obtener más información, consulta Capa de datos.
Por ejemplo, a partir de un objeto EditTextPreference
con una clave de "signature"
, se ve de la siguiente manera:
<EditTextPreference app:key="signature" app:title="Your signature"/>
Puedes recuperar el valor guardado para este Preference
a nivel global de la siguiente manera:
Kotlin
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */) val name = sharedPreferences.getString("signature", "")
Java
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */); String name = sharedPreferences.getString("signature", "");
Cómo detectar los cambios en los valores de Preference
Para detectar cambios en los valores de Preference
, puedes elegir entre dos interfaces:
En la siguiente tabla, se muestra cómo se diferencian las dos interfaces:
OnPreferenceChangeListener |
OnSharedPreferenceChangeListener |
---|---|
Se establece en un único Preference . |
Se aplica a todos los objetos Preference . |
Se llama cuando un Preference está a punto de cambiar su valor guardado, incluso si el valor pendiente es el mismo que el guardado. |
Se llama solo cuando cambia el valor guardado para un Preference . |
Solo se llama a través de la biblioteca Preference . Una parte independiente de la aplicación puede cambiar el valor guardado. |
Se llama cada vez que cambia el valor guardado, incluso si se trata de una parte independiente de la aplicación. |
Se llama antes de que se guarde el valor pendiente. | Se llama después de que se guarda el valor. |
Se llama cuando se usa SharedPreferences o PreferenceDataStore . |
Se llama solamente al usar SharedPreferences . |
Cómo implementar OnPreferenceChangeListener
Implementar un objeto OnPreferenceChangeListener
te permite escuchar un cambio pendiente en el valor de un objeto Preference
. Luego, puedes validar si el cambio ocurre. Por ejemplo, el siguiente código muestra cómo escuchar un cambio en el valor de un EditTextPreference
con una clave de "name"
:
Kotlin
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean { Log.e("preference", "Pending Preference value is: $newValue") return true }
Java
@Override public boolean onPreferenceChange(Preference preference, Object newValue) { Log.e("preference", "Pending Preference value is: " + newValue); return true; }
A continuación, debes configurar este objeto de escucha directamente con setOnPreferenceChangeListener()
de la siguiente manera:
Kotlin
preference.onPreferenceChangeListener = ...
Java
preference.setOnPreferenceChangeListener(...);
Implementa OnSharedPreferenceChangeListener
Al crear valores de Preference
persistentes con SharedPreferences
, también puedes usar un objeto SharedPreferences.OnSharedPreferenceChangeListener
para detectar cambios.
Esto te permite escuchar cuando se cambian los valores guardados por tu Preference
, como cuando se sincroniza la configuración con un servidor. En el siguiente ejemplo, se muestra cómo escuchar un cambio en el valor de un EditTextPreference
con una clave de "name"
:
Kotlin
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { if (key == "signature") { Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, "")) } }
Java
@Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals("signature")) { Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, "")); } }
Registra el objeto de escucha con registerOnSharedPreferenceChangedListener()
de la siguiente manera:
Kotlin
preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)
Java
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(...);
Kotlin
val listener: SharedPreferences.OnSharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener {...}
Java
SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {...}
Para una administración adecuada del ciclo de vida en tu Activity
o Fragment
, registra y cancela el registro de este objeto de escucha en las devoluciones de llamada onResume()
y onPause()
, como se muestra en el siguiente ejemplo:
Kotlin
override fun onResume() { super.onResume() preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this) } override fun onPause() { super.onPause() preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) }
Java
@Override public void onResume() { super.onResume(); getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); } @Override public void onPause() { super.onPause(); getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); }
Usa un almacén de datos personalizado
Aunque recomendamos que persistas objetos Preference
con SharedPreferences
, también puedes usar un almacén de datos personalizado. Un almacén de datos personalizado puede ser útil si tu aplicación conserva valores en una base de datos o si los valores son específicos del dispositivo, como se muestra en los siguientes ejemplos.
Implementa el almacén de datos
Para implementar un almacén de datos personalizado, crea una clase que extienda PreferenceDataStore
. En el siguiente ejemplo, se crea un almacén de datos que controla los valores de String
:
Kotlin
class DataStore : PreferenceDataStore() { override fun putString(key: String, value: String?) { // Save the value somewhere. } override fun getString(key: String, defValue: String?): String? { // Retrieve the value. } }
Java
public class DataStore extends PreferenceDataStore { @Override public void putString(String key, @Nullable String value) { // Save the value somewhere. } @Override @Nullable public String getString(String key, @Nullable String defValue) { // Retrieve the value. } }
Ejecuta las operaciones que requieran mucho tiempo fuera del subproceso principal para evitar bloquear la interfaz de usuario. Dado que es posible que los objetos Fragment
o Activity
que contienen el almacén de datos se destruyan mientras se conserva un valor, serializa los datos para no perder ningún valor que el usuario haya cambiado.
Habilita el almacén de datos
Después de implementar el almacén de datos, configúralo nuevo en onCreatePreferences()
para que los objetos Preference
conserven valores con el almacén de datos en lugar de usar el SharedPreferences
predeterminado. Puedes habilitar un almacén de datos para cada Preference
o para toda la jerarquía.
Si deseas habilitar un almacén de datos personalizado para un Preference
específico, llama a setPreferenceDataStore()
en el Preference
, como se muestra en el siguiente ejemplo:
Kotlin
val preference: Preference? = findPreference("key") preference?.preferenceDataStore = dataStore
Java
Preference preference = findPreference("key"); if (preference != null) { preference.setPreferenceDataStore(dataStore); }
Si deseas habilitar un almacén de datos personalizado para toda una jerarquía, llama a setPreferenceDataStore()
en PreferenceManager
:
Kotlin
val preferenceManager = preferenceManager preferenceManager.preferenceDataStore = dataStore
Java
PreferenceManager preferenceManager = getPreferenceManager(); preferenceManager.setPreferenceDataStore(dataStore);
Un almacén de datos configurado para un Preference
específico anula cualquier almacén de datos configurado para la jerarquía correspondiente. En la mayoría de los casos, configuras un almacén de datos para toda la jerarquía.