Comment Android SharedPreferences enregistre / stocke un objet


217

Nous devons obtenir des objets utilisateur à de nombreux endroits, qui contiennent de nombreux champs. Après la connexion, je souhaite enregistrer / stocker ces objets utilisateur. Comment mettre en œuvre ce genre de scénario?

Je ne peux pas le stocker comme ça:

SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefsEditor.putString("BusinessUnit", strBusinessUnit);

quel type de données que vous souhaitez stocker?
ilango j


Qu'entendiez-vous par ~ " et objet exécutif "? Veuillez vérifier votre grammaire avant de publier sur StackOverflow.
IgorGanapolsky

Vous pouvez utiliser cette bibliothèque qui a de nombreuses fonctionnalités ... github.com/moinkhan-in/PreferenceSpider
Moinkhan

Réponses:


549

Vous pouvez utiliser gson.jar pour stocker des objets de classe dans SharedPreferences . Vous pouvez télécharger ce pot depuis google-gson

Ou ajoutez la dépendance GSON dans votre fichier Gradle:

implementation 'com.google.code.gson:gson:2.8.5'

Création d'une préférence partagée:

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);

Sauver:

MyObject myObject = new MyObject;
//set variables of 'myObject', etc.

Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(myObject);
prefsEditor.putString("MyObject", json);
prefsEditor.commit();

À récupérer:

Gson gson = new Gson();
String json = mPrefs.getString("MyObject", "");
MyObject obj = gson.fromJson(json, MyObject.class);

9
Merci mon ami! Mais vous êtes incorrect dans la partie Enregistrer (ligne 3), le code correct est: String json = gson.toJson (myObject);
cesarferreira

Avez-vous besoin des 3 pots? Il y en a 3 dans ce lien. . .
coolcool1994

3
L'URL correcte pour télécharger le pot est: search.maven.org/…
Shajeel Afzal

2
Cela a un problème avec la référence circulaire qui mène à StackOverFlowException xD En savoir plus ici stackoverflow.com/questions/10209959/…
phuwin

1
@rozina yes Gson est mieux. Tout d'abord pour utiliser sérialiser, l'objet et chaque objet qu'il contient doivent implémenter l'interface sérialiser. Ce n'est pas nécessaire pour gson. gson fonctionne également très bien lorsque votre objet est une liste d'objets.
Neville Nazerane

36

Pour ajouter à la réponse de @ MuhammadAamirALi, vous pouvez utiliser Gson pour enregistrer et récupérer une liste d'objets

Enregistrer la liste des objets définis par l'utilisateur dans SharedPreferences

public static final String KEY_CONNECTIONS = "KEY_CONNECTIONS";
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();

User entity = new User();
// ... set entity fields

List<Connection> connections = entity.getConnections();
// convert java object to JSON format,
// and returned as JSON formatted string
String connectionsJSONString = new Gson().toJson(connections);
editor.putString(KEY_CONNECTIONS, connectionsJSONString);
editor.commit();

Obtenir la liste des objets définis par l'utilisateur à partir de SharedPreferences

String connectionsJSONString = getPreferences(MODE_PRIVATE).getString(KEY_CONNECTIONS, null);
Type type = new TypeToken < List < Connection >> () {}.getType();
List < Connection > connections = new Gson().fromJson(connectionsJSONString, type);

3
Qu'est-ce que "Type" là-bas? (dans la liste Get, 2e ligne).
gangadhars

15

Je sais que ce fil est un peu vieux. Mais je vais quand même poster ceci en espérant que cela pourrait aider quelqu'un. Nous pouvons stocker les champs de n'importe quel objet à préférence partagée en sérialisant l'objet en chaîne. Ici, j'ai utilisé GSONpour stocker n'importe quel objet à préférence partagée.

Enregistrer l'objet dans la préférence:

public static void saveObjectToSharedPreference(Context context, String preferenceFileName, String serializedObjectKey, Object object) {
    SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceFileName, 0);
    SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit();
    final Gson gson = new Gson();
    String serializedObject = gson.toJson(object);
    sharedPreferencesEditor.putString(serializedObjectKey, serializedObject);
    sharedPreferencesEditor.apply();
}

Récupérer l'objet de préférence:

public static <GenericClass> GenericClass getSavedObjectFromPreference(Context context, String preferenceFileName, String preferenceKey, Class<GenericClass> classType) {
    SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceFileName, 0);
    if (sharedPreferences.contains(preferenceKey)) {
        final Gson gson = new Gson();
        return gson.fromJson(sharedPreferences.getString(preferenceKey, ""), classType);
    }
    return null;
}

Remarque :

N'oubliez pas d'ajouter compile 'com.google.code.gson:gson:2.6.2'à dependenciesvotre gradle.

Exemple :

//assume SampleClass exists
SampleClass mObject = new SampleObject();

//to store an object
saveObjectToSharedPreference(context, "mPreference", "mObjectKey", mObject);

//to retrive object stored in preference
mObject = getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class);

Mettre à jour:

Comme @Sharp_Edge l'a souligné dans les commentaires, la solution ci-dessus ne fonctionne pas List.

Une légère modification de la signature de getSavedObjectFromPreference()- de Class<GenericClass> classTypeà Type classTyperendra cette solution généralisée. Signature de fonction modifiée,

public static <GenericClass> GenericClass getSavedObjectFromPreference(Context context, String preferenceFileName, String preferenceKey, Type classType)

Pour invoquer,

getSavedObjectFromPreference(context, "mPreference", "mObjectKey", (Type) SampleClass.class)

Codage heureux !


1
c'était vraiment utile merci. Pour quiconque ici souhaite faire un commentaire ... dois-je placer l'appel à saveObjectToSharedPreference dans onSaveInstanceState? Je l'ai maintenant dans onSaveInstanceState mais, étant donné que mon application collecte des données en temps réel toutes les 10 secondes, j'obtiens un hoquet de temps en temps et l'objet que j'enregistre avec saveObjectToSharedPreference perd certaines lectures. Toutes les pensées sont les bienvenues.
Frank Zappa

hé @FrankZappa, pardonnez-moi de ne pas bien comprendre votre problème mais vous y allez, essayez d'utiliser à la commitplace de apply. Cela pourrait vous aider.
tpk

Merci. Laissez-moi essayer d'expliquer. Mon application Android collecte des données en temps réel toutes les 10 secondes environ. Cette collecte de données n'utilise aucun objet, juste des variables globales et une logique. Ensuite, les données sont ensuite résumées et stockées dans un objet Java. J'utilise votre méthode ci-dessus pour stocker et récupérer mon objet Java dans / via SharedPreferences car a) à ma connaissance, je ne peux pas stocker d'objets dans onSavedInstanceState et b) lorsque l'écran tourne, mon objet est détruit et recréé. Par conséquent, j'utilise votre approche SharedPrefs donc lorsque l'écran tourne, mon objet ne perd pas ses valeurs. (suite)
Frank Zappa

J'ai placé votre routine saveObjectToSharedPreferences dans onSaveInstanceState. J'ai placé votre routine getSavedObjectFromPreference dans onRestoreInstanceState. Cependant, j'ai testé et j'ai encore obtenu un ensemble de mises à jour d'objets manqués en raison de la rotation de l'écran. Par conséquent, dois-je déplacer l'appel à saveObjectToSharedPreferences plus près de ma logique actuelle? Enfin, à quelle méthode la validation et l'application s'appliquent-elles?
Frank Zappa

1
@ 2943 Votre solution est superbe, mais si j'ai une liste par exemple, List<CustomClass>comment dois-je faire? getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class)n'accepte pas List<CustomClass>.class:(
Sharp Edge

6

Mieux vaut créer une Constantsclasse globale pour enregistrer des clés ou des variables pour récupérer ou enregistrer des données.

Pour enregistrer des données, appelez cette méthode pour enregistrer des données de partout.

public static void saveData(Context con, String variable, String data)
{
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(con);
    prefs.edit().putString(variable, data).commit();
}

Utilisez-le pour obtenir des données.

public static String getData(Context con, String variable, String defaultValue)
{
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(con);
    String data = prefs.getString(variable, defaultValue);
    return data;
}

et une méthode quelque chose comme ça fera l'affaire

public static User getUserInfo(Context con)
{
    String id =  getData(con, Constants.USER_ID, null);
    String name =  getData(con, Constants.USER_NAME, null);
    if(id != null && name != null)
    {
            User user = new User(); //Hope you will have a user Object.
            user.setId(id);
            user.setName(name);
            //Here set other credentials.
            return user;
    }
    else
    return null;
}

Afin de récupérer les données, qu'est-ce que je passe comme «variable» et «defaultValue»?
Alex

Ne créez jamais de classe Constantes. Cela rend votre code fortement couplé et dispersé en même temps.
Miha_x64

5

Essayez cette meilleure façon:

PreferenceConnector.java

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class PreferenceConnector {
    public static final String PREF_NAME = "ENUMERATOR_PREFERENCES";
    public static final String PREF_NAME_REMEMBER = "ENUMERATOR_REMEMBER";
    public static final int MODE = Context.MODE_PRIVATE;


    public static final String name = "name";


    public static void writeBoolean(Context context, String key, boolean value) {
        getEditor(context).putBoolean(key, value).commit();
    }

    public static boolean readBoolean(Context context, String key,
            boolean defValue) {
        return getPreferences(context).getBoolean(key, defValue);
    }

    public static void writeInteger(Context context, String key, int value) {
        getEditor(context).putInt(key, value).commit();

    }

    public static int readInteger(Context context, String key, int defValue) {
        return getPreferences(context).getInt(key, defValue);
    }

    public static void writeString(Context context, String key, String value) {
        getEditor(context).putString(key, value).commit();

    }

    public static String readString(Context context, String key, String defValue) {
        return getPreferences(context).getString(key, defValue);
    }

    public static void writeLong(Context context, String key, long value) {
        getEditor(context).putLong(key, value).commit();
    }

    public static long readLong(Context context, String key, long defValue) {
        return getPreferences(context).getLong(key, defValue);
    }

    public static SharedPreferences getPreferences(Context context) {
        return context.getSharedPreferences(PREF_NAME, MODE);
    }

    public static Editor getEditor(Context context) {
        return getPreferences(context).edit();
    }

}

Écrivez la valeur:

PreferenceConnector.writeString(this, PreferenceConnector.name,"Girish");

Et obtenez de la valeur en utilisant:

String name= PreferenceConnector.readString(this, PreferenceConnector.name, "");

2
Qu'est-ce que cela a à voir avec l'enregistrement d'un objet dans SharedPreferences sur Android?
IgorGanapolsky

Plus d'informations sur l'utilisation de Sharedpreferences peuvent être trouvées sur stackoverflow.com/a/2614771/1815624 note que vous voudrez peut-être utiliser à la return PreferenceManager.getDefaultSharedPreferences(context);place dereturn context.getSharedPreferences(PREF_NAME, MODE);
CrandellWS

3

Vous n'avez pas indiqué ce que vous faites avec l' prefsEditorobjet après cela, mais pour conserver les données de préférence, vous devez également utiliser:

prefsEditor.commit();

2

Voir ici, cela peut vous aider:

public static boolean setObject(Context context, Object o) {
        Field[] fields = o.getClass().getFields();
        SharedPreferences sp = context.getSharedPreferences(o.getClass()
                .getName(), Context.MODE_PRIVATE);
        Editor editor = sp.edit();
        for (int i = 0; i < fields.length; i++) {
            Class<?> type = fields[i].getType();
            if (isSingle(type)) {
                try {
                    final String name = fields[i].getName();
                    if (type == Character.TYPE || type.equals(String.class)) {
                        Object value = fields[i].get(o);
                        if (null != value)
                            editor.putString(name, value.toString());
                    } else if (type.equals(int.class)
                            || type.equals(Short.class))
                        editor.putInt(name, fields[i].getInt(o));
                    else if (type.equals(double.class))
                        editor.putFloat(name, (float) fields[i].getDouble(o));
                    else if (type.equals(float.class))
                        editor.putFloat(name, fields[i].getFloat(o));
                    else if (type.equals(long.class))
                        editor.putLong(name, fields[i].getLong(o));
                    else if (type.equals(Boolean.class))
                        editor.putBoolean(name, fields[i].getBoolean(o));

                } catch (IllegalAccessException e) {
                    LogUtils.e(TAG, e);
                } catch (IllegalArgumentException e) {
                    LogUtils.e(TAG, e);
                }
            } else {
                // FIXME 是对象则不写入
            }
        }

        return editor.commit();
    }

https://github.com/AltasT/PreferenceVObjectFile/blob/master/PreferenceVObjectFile/src/com/altas/lib/PreferenceUtils.java


2
Pourriez-vous expliquer un peu plus le code car il ne représente actuellement qu'un "tas de code".
Werner

1

Une autre façon d'enregistrer et de restaurer un objet à partir de préférences partagées Android sans utiliser le format Json

private static ExampleObject getObject(Context c,String db_name){
            SharedPreferences sharedPreferences = c.getSharedPreferences(db_name, Context.MODE_PRIVATE);
            ExampleObject o = new ExampleObject();
            Field[] fields = o.getClass().getFields();
            try {
                for (Field field : fields) {
                    Class<?> type = field.getType();
                    try {
                        final String name = field.getName();
                        if (type == Character.TYPE || type.equals(String.class)) {
                            field.set(o,sharedPreferences.getString(name, ""));
                        } else if (type.equals(int.class) || type.equals(Short.class))
                            field.setInt(o,sharedPreferences.getInt(name, 0));
                        else if (type.equals(double.class))
                            field.setDouble(o,sharedPreferences.getFloat(name, 0));
                        else if (type.equals(float.class))
                            field.setFloat(o,sharedPreferences.getFloat(name, 0));
                        else if (type.equals(long.class))
                            field.setLong(o,sharedPreferences.getLong(name, 0));
                        else if (type.equals(Boolean.class))
                            field.setBoolean(o,sharedPreferences.getBoolean(name, false));
                        else if (type.equals(UUID.class))
                            field.set(
                                    o,
                                    UUID.fromString(
                                            sharedPreferences.getString(
                                                    name,
                                                    UUID.nameUUIDFromBytes("".getBytes()).toString()
                                            )
                                    )
                            );

                    } catch (IllegalAccessException e) {
                        Log.e(StaticConfig.app_name, "IllegalAccessException", e);
                    } catch (IllegalArgumentException e) {
                        Log.e(StaticConfig.app_name, "IllegalArgumentException", e);
                    }
                }
            } catch (Exception e) {
                System.out.println("Exception: " + e);
            }
            return o;
        }
        private static void setObject(Context context, Object o, String db_name) {
            Field[] fields = o.getClass().getFields();
            SharedPreferences sp = context.getSharedPreferences(db_name, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            for (Field field : fields) {
                Class<?> type = field.getType();
                try {
                    final String name = field.getName();
                    if (type == Character.TYPE || type.equals(String.class)) {
                        Object value = field.get(o);
                        if (value != null)
                            editor.putString(name, value.toString());
                    } else if (type.equals(int.class) || type.equals(Short.class))
                        editor.putInt(name, field.getInt(o));
                    else if (type.equals(double.class))
                        editor.putFloat(name, (float) field.getDouble(o));
                    else if (type.equals(float.class))
                        editor.putFloat(name, field.getFloat(o));
                    else if (type.equals(long.class))
                        editor.putLong(name, field.getLong(o));
                    else if (type.equals(Boolean.class))
                        editor.putBoolean(name, field.getBoolean(o));
                    else if (type.equals(UUID.class))
                        editor.putString(name, field.get(o).toString());

                } catch (IllegalAccessException e) {
                    Log.e(StaticConfig.app_name, "IllegalAccessException", e);
                } catch (IllegalArgumentException e) {
                    Log.e(StaticConfig.app_name, "IllegalArgumentException", e);
                }
            }

            editor.apply();
        }

1

Vous pouvez enregistrer un objet dans les préférences sans utiliser de bibliothèque, tout d'abord votre classe d'objet doit implémenter Serializable:

public class callModel implements Serializable {

private long pointTime;
private boolean callisConnected;

public callModel(boolean callisConnected,  long pointTime) {
    this.callisConnected = callisConnected;
    this.pointTime = pointTime;
}
public boolean isCallisConnected() {
    return callisConnected;
}
public long getPointTime() {
    return pointTime;
}

}

Ensuite, vous pouvez facilement utiliser ces deux méthodes pour convertir un objet en chaîne et une chaîne en objet:

 public static <T extends Serializable> T stringToObjectS(String string) {
    byte[] bytes = Base64.decode(string, 0);
    T object = null;
    try {
        ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
        object = (T) objectInputStream.readObject();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return object;
}

 public static String objectToString(Parcelable object) {
    String encoded = null;
    try {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(object);
        objectOutputStream.close();
        encoded = new String(Base64.encodeToString(byteArrayOutputStream.toByteArray(), 0));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return encoded;
}

Sauver:

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);
Editor prefsEditor = mPrefs.edit();
prefsEditor.putString("MyObject", objectToString(callModelObject));
prefsEditor.commit();

Lire

String value= mPrefs.getString("MyObject", "");
MyObject obj = stringToObjectS(value);

Vous pouvez éviter le codage Base64 et l'échappement XML en écrivant simplement ces octets dans un fichier séparé.
Miha_x64

1

Étape 1: Copiez collez ces deux fonctions dans votre fichier java.

 public void setDefaults(String key, String value, Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString(key, value);
        editor.commit();
    }


    public static String getDefaults(String key, Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(key, null);
    }

Étape 2: pour économiser l'utilisation:

 setDefaults("key","value",this);

pour récupérer l'utilisation:

String retrieve= getDefaults("key",this);

Vous pouvez définir différentes préférences partagées en utilisant différents noms de clés tels que:

setDefaults("key1","xyz",this);

setDefaults("key2","abc",this);

setDefaults("key3","pqr",this);

1

Si vous voulez stocker tout l'objet que vous obtenez en réponse, cela peut être réalisé en faisant quelque chose comme,

Créez d'abord une méthode qui convertit votre JSON en chaîne dans votre classe util comme ci-dessous.

 public static <T> T fromJson(String jsonString, Class<T> theClass) {
    return new Gson().fromJson(jsonString, theClass);
}

Dans la classe des préférences partagées, faites quelque chose comme:

 public void storeLoginResponse(yourResponseClass objName) {

    String loginJSON = UtilClass.toJson(customer);
    if (!TextUtils.isEmpty(customerJSON)) {
        editor.putString(AppConst.PREF_CUSTOMER, customerJSON);
        editor.commit();
    }
}

puis créez une méthode pour getPreferences

public Customer getCustomerDetails() {
    String customerDetail = pref.getString(AppConst.PREF_CUSTOMER, null);
    if (!TextUtils.isEmpty(customerDetail)) {
        return GSONConverter.fromJson(customerDetail, Customer.class);
    } else {
        return new Customer();
    }
}

Ensuite, appelez simplement la première méthode lorsque vous obtenez une réponse et la seconde lorsque vous devez obtenir des données à partir des préférences de partage comme

String token = SharedPrefHelper.get().getCustomerDetails().getAccessToken();

c'est tout.

J'espère que cela vous aidera.

Happy Coding();


1

J'ai eu du mal à utiliser la réponse acceptée pour accéder aux données de préférence partagée dans toutes les activités. Dans ces étapes, vous donnez à getSharedPreferences un nom pour y accéder.

Ajoutez la dépendance suivante dans le fichier build.gradel (Module: app) sous Gradle Scripts:

implementation 'com.google.code.gson:gson:2.8.5'

Sauver:

MyObject myObject = new MyObject;
//set variables of 'myObject', etc.

SharedPreferences mPrefs = getSharedPreferences("Name", Context.MODE_PRIVATE);

Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(myObject);
prefsEditor.putString("Key", json);
prefsEditor.commit();

Pour récupérer dans une autre activité:

SharedPreferences mPrefs = getSharedPreferences("Name", Context.MODE_PRIVATE);

Gson gson = new Gson();
String json = mPrefs.getString("Key", "");
MyObject obj = gson.fromJson(json, MyObject.class);

1
// SharedPrefHelper is a class contains the get and save sharedPrefernce data
public class SharedPrefHelper {

    // save data in sharedPrefences
    public static void setSharedOBJECT(Context context, String key, 
                                           Object value) {

        SharedPreferences sharedPreferences =  context.getSharedPreferences(
                context.getPackageName(), Context.MODE_PRIVATE);

        SharedPreferences.Editor prefsEditor = sharedPreferences.edit();
        Gson gson = new Gson();
        String json = gson.toJson(value);
        prefsEditor.putString(key, json);
        prefsEditor.apply();
    }

    // get data from sharedPrefences 
    public static Object getSharedOBJECT(Context context, String key) {

         SharedPreferences sharedPreferences = context.getSharedPreferences(
                           context.getPackageName(), Context.MODE_PRIVATE);

        Gson gson = new Gson();
        String json = sharedPreferences.getString(key, "");
        Object obj = gson.fromJson(json, Object.class);
        User objData = new Gson().fromJson(obj.toString(), User.class);
        return objData;
    }
}
// save data in your activity

User user = new User("Hussein","h@h.com","3107310890983");        
SharedPrefHelper.setSharedOBJECT(this,"your_key",user);        
User data = (User) SharedPrefHelper.getSharedOBJECT(this,"your_key");

Toast.makeText(this,data.getName()+"\n"+data.getEmail()+"\n"+data.getPhone(),Toast.LENGTH_LONG).show();
// User is the class you want to save its objects

public class User {

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    private String name,email,phone;
    public User(String name,String email,String phone){
          this.name=name;
          this.email=email;
          this.phone=phone;
    }
}
// put this in gradle

compile 'com.google.code.gson:gson:2.7'

j'espère que cela vous aide :)


1

Voici un aperçu de l' utilisation des propriétés déléguées Kotlin que j'ai récupérées ici , mais développées et permet un mécanisme simple pour obtenir / définir les propriétés SharedPreference.

Pour String, Int, Long, Floatou Boolean, il utilise le getter standard SharePreference (s) et poseur (s). Cependant, pour toutes les autres classes de données, il utilise GSON pour sérialiser en unString , pour le setter. Désérialise ensuite l'objet de données, pour le getter.

Semblable à d'autres solutions, cela nécessite d'ajouter GSON en tant que dépendance dans votre fichier de notes:

implementation 'com.google.code.gson:gson:2.8.6'

Voici un exemple d'une classe de données simple que nous souhaiterions pouvoir enregistrer et stocker dans SharedPreferences:

data class User(val first: String, val last: String)

Voici la seule classe qui implémente les délégués de propriété:

object UserPreferenceProperty : PreferenceProperty<User>(
    key = "USER_OBJECT",
    defaultValue = User(first = "Jane", last = "Doe"),
    clazz = User::class.java)

object NullableUserPreferenceProperty : NullablePreferenceProperty<User?, User>(
    key = "NULLABLE_USER_OBJECT",
    defaultValue = null,
    clazz = User::class.java)

object FirstTimeUser : PreferenceProperty<Boolean>(
        key = "FIRST_TIME_USER",
        defaultValue = false,
        clazz = Boolean::class.java
)

sealed class PreferenceProperty<T : Any>(key: String,
                                         defaultValue: T,
                                         clazz: Class<T>) : NullablePreferenceProperty<T, T>(key, defaultValue, clazz)

@Suppress("UNCHECKED_CAST")
sealed class NullablePreferenceProperty<T : Any?, U : Any>(private val key: String,
                                                           private val defaultValue: T,
                                                           private val clazz: Class<U>) : ReadWriteProperty<Any, T> {

    override fun getValue(thisRef: Any, property: KProperty<*>): T = HandstandApplication.appContext().getPreferences()
            .run {
                when {
                    clazz.isAssignableFrom(String::class.java) -> getString(key, defaultValue as String?) as T
                    clazz.isAssignableFrom(Int::class.java) -> getInt(key, defaultValue as Int) as T
                    clazz.isAssignableFrom(Long::class.java) -> getLong(key, defaultValue as Long) as T
                    clazz.isAssignableFrom(Float::class.java) -> getFloat(key, defaultValue as Float) as T
                    clazz.isAssignableFrom(Boolean::class.java) -> getBoolean(key, defaultValue as Boolean) as T
                    else -> getObject(key, defaultValue, clazz)
                }
            }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: T) = HandstandApplication.appContext().getPreferences()
            .edit()
            .apply {
                when {
                    clazz.isAssignableFrom(String::class.java) -> putString(key, value as String?) as T
                    clazz.isAssignableFrom(Int::class.java) -> putInt(key, value as Int) as T
                    clazz.isAssignableFrom(Long::class.java) -> putLong(key, value as Long) as T
                    clazz.isAssignableFrom(Float::class.java) -> putFloat(key, value as Float) as T
                    clazz.isAssignableFrom(Boolean::class.java) -> putBoolean(key, value as Boolean) as T
                    else -> putObject(key, value)
                }
            }
            .apply()

    private fun Context.getPreferences(): SharedPreferences = getSharedPreferences(APP_PREF_NAME, Context.MODE_PRIVATE)

    private fun <T, U> SharedPreferences.getObject(key: String, defValue: T, clazz: Class<U>): T =
            Gson().fromJson(getString(key, null), clazz) as T ?: defValue

    private fun <T> SharedPreferences.Editor.putObject(key: String, value: T) = putString(key, Gson().toJson(value))

    companion object {
        private const val APP_PREF_NAME = "APP_PREF"
    }
}

Remarque: vous ne devriez pas avoir besoin de mettre à jour quoi que ce soit dans le sealed class. Les propriétés délégués sont l'objet / singletons UserPreferenceProperty, NullableUserPreferencePropertyet FirstTimeUser.

Pour configurer un nouvel objet de données pour enregistrer / obtenir à partir de SharedPreferences, il est maintenant aussi simple que d'ajouter quatre lignes:

object NewPreferenceProperty : PreferenceProperty<String>(
        key = "NEW_PROPERTY",
        defaultValue = "",
        clazz = String::class.java)

Enfin, vous pouvez lire / écrire des valeurs dans SharedPreferences en utilisant simplement le bymot clé:

private var user: User by UserPreferenceProperty
private var nullableUser: User? by NullableUserPreferenceProperty
private var isFirstTimeUser: Boolean by 

Log.d("TAG", user) // outputs the `defaultValue` for User the first time
user = User(first = "John", last = "Doe") // saves this User to the Shared Preferences
Log.d("TAG", user) // outputs the newly retrieved User (John Doe) from Shared Preferences

0

Si votre objet est complexe, je suggère de le sérialiser / XML / JSON et d'enregistrer ce contenu sur la carte SD. Vous pouvez trouver des informations supplémentaires sur la façon de sauvegarder sur un stockage externe ici: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal


Cela ne nécessitera-t-il pas une autorisation supplémentaire (carte SD)?
rishabh

Oui, car vous écrivez sur la carte SD.
trenpixster

1
D'après mon expérience, les autorisations moindres nécessaires à l'utilisateur, mieux c'est. La carte SD devrait être un choix secondaire, si l'utilisation de Gson comme indiqué ci-dessus n'est pas une option viable.
rishabh

Ouais, je suis également d'accord avec cela; Ce n'est que si le résultat JSON est suffisamment grand que la carte SD doit être une option. C'est un compromis, je dirais.
trenpixster

0

il y a deux fichiers résolus tout votre problème sur les préférences partagées

1) AppPersistence.java

    public class AppPersistence {
    public enum keys {
        USER_NAME, USER_ID, USER_NUMBER, USER_EMAIL, USER_ADDRESS, CITY, USER_IMAGE,
        DOB, MRG_Anniversary, COMPANY, USER_TYPE, support_phone
    }

    private static AppPersistence mAppPersistance;
    private SharedPreferences sharedPreferences;

    public static AppPersistence start(Context context) {
        if (mAppPersistance == null) {
            mAppPersistance = new AppPersistence(context);
        }
        return mAppPersistance;
    }

    private AppPersistence(Context context) {
        sharedPreferences = context.getSharedPreferences(context.getString(R.string.prefrence_file_name),
                Context.MODE_PRIVATE);
    }

    public Object get(Enum key) {
        Map<String, ?> all = sharedPreferences.getAll();
        return all.get(key.toString());
    }

    void save(Enum key, Object val) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        if (val instanceof Integer) {
            editor.putInt(key.toString(), (Integer) val);
        } else if (val instanceof String) {
            editor.putString(key.toString(), String.valueOf(val));
        } else if (val instanceof Float) {
            editor.putFloat(key.toString(), (Float) val);
        } else if (val instanceof Long) {
            editor.putLong(key.toString(), (Long) val);
        } else if (val instanceof Boolean) {
            editor.putBoolean(key.toString(), (Boolean) val);
        }
        editor.apply();
    }

    void remove(Enum key) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.remove(key.toString());
        editor.apply();
    }

    public void removeAll() {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.clear();
        editor.apply();
    }
}

2) AppPreference.java

public static void setPreference(Context context, Enum Name, String Value) {
        AppPersistence.start(context).save(Name, Value);
    }

    public static String getPreference(Context context, Enum Name) {
        return (String) AppPersistence.start(context).get(Name);
    }

    public static void removePreference(Context context, Enum Name) {
        AppPersistence.start(context).remove(Name);
    }
}

vous pouvez maintenant enregistrer, supprimer ou faire comme,

-enregistrer

AppPreference.setPreference(context, AppPersistence.keys.USER_ID, userID);

-retirer

AppPreference.removePreference(context, AppPersistence.keys.USER_ID);

-avoir

 AppPreference.getPreference(context, AppPersistence.keys.USER_ID);

0

Stocker des données dans SharedPreference

SharedPreferences mprefs = getSharedPreferences(AppConstant.PREFS_NAME, MODE_PRIVATE)
mprefs.edit().putString(AppConstant.USER_ID, resUserID).apply();

0

Ma classe d'utilitaires pour enregistrer la liste SharedPreferences

public class SharedPrefApi {
    private SharedPreferences sharedPreferences;
    private Gson gson;

    public SharedPrefApi(Context context, Gson gson) {
        this.sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        this.gson = gson;
    } 

    ...

    public <T> void putObject(String key, T value) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, gson.toJson(value));
        editor.apply();
    }

    public <T> T getObject(String key, Class<T> clazz) {
        return gson.fromJson(getString(key, null), clazz);
    }
}

En utilisant

// for save
sharedPrefApi.putList(SharedPrefApi.Key.USER_LIST, userList);

// for retrieve
List<User> userList = sharedPrefApi.getList(SharedPrefApi.Key.USER_LIST, User.class);

.
Code complet de mes utils // vérifier en utilisant l'exemple dans le code d'activité


0

J'ai utilisé jackson pour stocker mes objets ( jackson ).

Ajout de la bibliothèque jackson pour gradle:

api 'com.fasterxml.jackson.core:jackson-core:2.9.4'
api 'com.fasterxml.jackson.core:jackson-annotations:2.9.4'
api 'com.fasterxml.jackson.core:jackson-databind:2.9.4'

Ma classe de test:

public class Car {
    private String color;
    private String type;
    // standard getters setters
}

Objet Java en JSON:

ObjectMapper objectMapper = new ObjectMapper();
String carAsString = objectMapper.writeValueAsString(car);

Stockez-le dans les préférences partagées:

preferences.edit().car().put(carAsString).apply();

Restaurez-le à partir des préférences partagées:

ObjectMapper objectMapper = new ObjectMapper();
Car car = objectMapper.readValue(preferences.car().get(), Car.class);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.