Clase Utilitaria para Encapsular SharedPreferences en Android

SharedPreferences en Android es un mecanismo de almacenamiento diseñado para datos simples y de pequeño volumen, como configuraciones de la aplicación (por ejemplo, preferencias de sonido o vibración).

Los datos se almacenan como pares clave-valor en formato XML deentro del directorio /data/data/<nombre del paquete>/shared_prefs, con un elemento raíz <map.../> donde cada hijo representa un par clave-valor.

Existen tres formas principales de obtener una instancia de SharedPreferences:

  • Context.getSharedPreferences(String nombre, int modo): Especifica el nombre del archivo y el modo (generalmente MODE_PRIVATE o 0) para restringir el acceso a la aplicación actual.
  • Activity.getPreferences(int modo): Usa el nombre de la clase Activity como nombre de archivo y es privado a esa Activity.
  • PreferenceManager.getDefaultSharedPreferences(Context contexto): Método estático que genera un archivo con el prefijo del nombre del paquete de la aplicación, accesible globalmente dentro de la app.

Una vez obtenido el objeto SharedPreferences, se puede leer datos mediante métodos como getInt(String clave, int valorPorDefecto), que devuelve un entero o un valor por defecto si la clave no existe. Otros métodos útiles incluyen getAll() para recuperar todos los pares, y contains(String clave) para verificar la existencia de una clave. También se pueden registrar listeners a través de registerOnSharedPreferenceChangeListener para detectar cambios.

Para mdoificar datos, se usa edit() para obtener un objeto SharedPreferences.Editor, que proporciona métodos como putInt(String clave, int valor). Tras usar putXXX, se debe invocar commit() o apply() para aplicar los cambios. commit() es síncrono y devuelve un booleano indicando éxito, mientras que apply() es asíncrono y no retorna valor, ofreciendo mejor rendimiento en operaciones concurrentes. Nota: después de remove(String clave), se requiere commit() para que surta efecto.

A continuación, un ejemplo de uso en una Activity con una interfaz simple para gestionar datos:

<!-- Archivo de layout XML -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/textViewDisplay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Contenido inicial" />

    <Button
        android:id="@+id/buttonSave"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="handleClick"
        android:text="Guardar" />

    <Button
        android:id="@+id/buttonLoad"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="handleClick"
        android:text="Cargar" />

    <Button
        android:id="@+id/buttonUpdate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="handleClick"
        android:text="Actualizar" />
</LinearLayout>
// Código Java en la Activity
package com.ejemplo.gestorpreferencias;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceManager;

public class GestorActivity extends AppCompatActivity {
    private TextView displayView;
    private SharedPreferences prefs;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_gestor);
        displayView = findViewById(R.id.textViewDisplay);
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
    }

    public void handleClick(View view) {
        SharedPreferences.Editor editor = prefs.edit();
        int viewId = view.getId();
        if (viewId == R.id.buttonSave) {
            editor.putString("nombre_usuario", "usuario_ejemplo");
            editor.putInt("nivel_acceso", 3);
            if (editor.commit()) {
                Toast.makeText(this, "Datos almacenados", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Error al guardar", Toast.LENGTH_SHORT).show();
            }
        } else if (viewId == R.id.buttonLoad) {
            String nombre = prefs.getString("nombre_usuario", "invitado");
            int nivel = prefs.getInt("nivel_acceso", 1);
            displayView.setText("Usuario: " + nombre + " | Nivel: " + nivel);
        } else if (viewId == R.id.buttonUpdate) {
            editor.putString("nombre_usuario", "nuevo_usuario");
            if (editor.commit()) {
                Toast.makeText(this, "Datos actualizados", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Error al actualizar", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

Este ejemplo almacena un nombre y un nivel de acceso. Al cargar, se leen los valores o se usan predeterminados. Al actualizar, se modifica el nombre existente.

Para simplificar el acceso recurrente, se puede crear una clase utilitaria con métodos genéricos:

// Clase utilitaria para SharedPreferences
import android.content.Context;
import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;

public class PreferenciasHelper {
    public static void guardarValor(Context contexto, String clave, Object valor) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(contexto);
        SharedPreferences.Editor editor = prefs.edit();
        String tipoValor = valor.getClass().getSimpleName();
        switch (tipoValor) {
            case "Integer":
                editor.putInt(clave, (Integer) valor);
                break;
            case "Boolean":
                editor.putBoolean(clave, (Boolean) valor);
                break;
            case "String":
                editor.putString(clave, (String) valor);
                break;
            case "Float":
                editor.putFloat(clave, (Float) valor);
                break;
            case "Long":
                editor.putLong(clave, (Long) valor);
                break;
        }
        editor.apply();
    }

    public static Object obtenerValor(Context contexto, String clave, Object valorPorDefecto) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(contexto);
        String tipoDefault = valorPorDefecto.getClass().getSimpleName();
        switch (tipoDefault) {
            case "Integer":
                return prefs.getInt(clave, (Integer) valorPorDefecto);
            case "Boolean":
                return prefs.getBoolean(clave, (Boolean) valorPorDefecto);
            case "String":
                return prefs.getString(clave, (String) valorPorDefecto);
            case "Float":
                return prefs.getFloat(clave, (Float) valorPorDefecto);
            case "Long":
                return prefs.getLong(clave, (Long) valorPorDefecto);
            default:
                return null;
        }
    }
}

Esta utilidad permite guardar y recuperar valores de diferantes tipos usando reflexión básica, con apply() para operaciones no bloqueantes.

Etiquetas: Android SharedPreferences java Almacenamiento de Datos Encapsulación

Publicado el 6-29 06:39