stocker et récupérer un objet de classe dans la préférence partagée


111

Dans Android, pouvons-nous stocker un objet d'une classe dans une préférence partagée et récupérer l'objet plus tard?

Si c'est possible, comment le faire? Si ce n'est pas possible, quelles sont les autres possibilités de le faire?

Je sais que la sérialisation est une option, mais je recherche des possibilités utilisant la préférence partagée.


J'ajoute une bibliothèque d'aide au cas où quelqu'un en aurait besoin: github.com/ionull/objectify
Tsung Goh


Voici une réponse à une question similaire.
tpk le


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

Réponses:


15

Pas possible.

Vous ne pouvez stocker que des valeurs simples dans SharedPrefences SharePreferences.Editor

Qu'en est-il en particulier de la classe que vous devez économiser?


1
Merci.Je veux stocker des données membres de la classe.Et je ne veux pas stocker chaque valeur des membres de données en utilisant la préférence partagée.Je veux les stocker en tant qu'objet.Si la préférence n'est pas partagée, quelles sont mes autres options?
androidGuy

5
Sérialisez-le et stockez-le, dans une base de données (SQLite) / dans un fichier plat.
Blundell

5
La réponse n'est pas complète. La solution possible est de transformer le pojo en ByteArrayOutPutStream et de l'enregistrer en tant que String dans les SharedPreferences
rallat le

27
une autre option est enregistrée en tant que json, puis mappée à nouveau. Avec GSON ou jackSON, c'est vraiment facile
rallye le

2
permettez-moi de ramener ma machine à remonter le temps en 2011 et de comprendre cela
Blundell

324

Oui, nous pouvons le faire en utilisant Gson

Télécharger le code de travail depuis GitHub

SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);

Pour sauver

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

Oublier

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

Mise à jour1

La dernière version de GSON peut être téléchargée depuis github.com/google/gson .

Mise à jour2

Si vous utilisez Gradle / Android Studio, mettez simplement ce qui suit dans build.gradlela section des dépendances -

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

ne fonctionne pas dans mon cas. Même après avoir mis jar dans les bibliothèques et défini le chemin de construction, la classe Gson ne se résout pas.
Shirish Herwade

Nettoyez le projet puis essayez @ShirishHerwade
Parag Chauhan

@parag qui ne fonctionne pas non plus. Pouvez-vous s'il vous plaît me dire les étapes à suivre pour utiliser ce pot pour supprimer l'erreur ci-dessus. Parce que j'ai ajouté avec succès ce fichier jar dans le dossier libs, puis dans "java build path", j'ai également essayé d'ajouter du json de stockage externe sur mon bureau
Shirish Herwade

7
Cette réponse serait encore meilleure si elle mentionnait également ses limites. Quel type d'objet pouvons-nous et ne pouvons-nous pas stocker et récupérer de cette manière? De toute évidence, cela ne fonctionnera pas pour toutes les classes.
wvdz

3
String json = gson.toJson("MyObject");devrait être l'objet et non une chaîne.
Ahmed Hegazy

44

nous pouvons utiliser Outputstream pour sortir notre objet dans la mémoire interne. Et convertir en chaîne puis enregistrer de préférence. Par exemple:

    mPrefs = getPreferences(MODE_PRIVATE);
    SharedPreferences.Editor ed = mPrefs.edit();
    ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();

    ObjectOutputStream objectOutput;
    try {
        objectOutput = new ObjectOutputStream(arrayOutputStream);
        objectOutput.writeObject(object);
        byte[] data = arrayOutputStream.toByteArray();
        objectOutput.close();
        arrayOutputStream.close();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Base64OutputStream b64 = new Base64OutputStream(out, Base64.DEFAULT);
        b64.write(data);
        b64.close();
        out.close();

        ed.putString(key, new String(out.toByteArray()));

        ed.commit();
    } catch (IOException e) {
        e.printStackTrace();
    }

lorsque nous devons extraire un objet de la préférence. Utilisez le code comme ci-dessous

    byte[] bytes = mPrefs.getString(indexName, "{}").getBytes();
    if (bytes.length == 0) {
        return null;
    }
    ByteArrayInputStream byteArray = new ByteArrayInputStream(bytes);
    Base64InputStream base64InputStream = new Base64InputStream(byteArray, Base64.DEFAULT);
    ObjectInputStream in;
    in = new ObjectInputStream(base64InputStream);
    MyObject myObject = (MyObject) in.readObject();

Salut, je sais que cela a été publié il y a quelque temps, mais êtes-vous sûr que le code que vous avez pour extraire l'objet stocké est correct? J'obtiens plusieurs erreurs sur les 2 dernières lignes en me plaignant de la façon dont les constructeurs explicites doivent être définis plutôt que d'avoir simplement "new ObjectInputStream (byteArray)". Merci pour l'aide!
Wakka Wakka Wakka

Salut, je reçois soudainement une exception EOFException sur in = new ObjectInputStream (base64InputStream); Je l'écris aux préférences partagées exactement de la même manière que vous le faites. Que pensez-vous pourrait être faux?
marienke

Avez-vous une exception lorsque vous écrivez Object dans pref? À partir du SDK: lève une exception EOFException lorsqu'un programme rencontre la fin d'un fichier ou d'un flux lors d'une opération d'entrée.
Kislingk

Félicitations, c'est la meilleure solution que j'ai trouvée pour ce problème jusqu'à présent. Pas de dépendances. Cependant, il convient de noter que pour pouvoir utiliser ObjectOutput / InputStream pour un objet, ledit objet et tous les objets personnalisés qu'il contient doivent implémenter l'interface Serializable.
user1112789

8

J'ai eu le même problème, voici ma solution:

J'ai la classe MyClass et ArrayList <MyClass> que je souhaite enregistrer dans les préférences partagées. Au début, j'ai ajouté une méthode à MyClass qui le convertit en objet JSON:

public JSONObject getJSONObject() {
    JSONObject obj = new JSONObject();
    try {
        obj.put("id", this.id);
        obj.put("name", this.name);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return obj;
}

Ensuite, voici la méthode pour enregistrer l'objet "ArrayList <MyClass> items":

SharedPreferences mPrefs = context.getSharedPreferences("some_name", 0);
    SharedPreferences.Editor editor = mPrefs.edit();

    Set<String> set= new HashSet<String>();
    for (int i = 0; i < items.size(); i++) {
        set.add(items.get(i).getJSONObject().toString());
    }

    editor.putStringSet("some_name", set);
    editor.commit();

Et voici la méthode pour récupérer l'objet:

public static ArrayList<MyClass> loadFromStorage() {
    SharedPreferences mPrefs = context.getSharedPreferences("some_name", 0);

    ArrayList<MyClass> items = new ArrayList<MyClass>();

    Set<String> set = mPrefs.getStringSet("some_name", null);
    if (set != null) {
        for (String s : set) {
            try {
                JSONObject jsonObject = new JSONObject(s);
                Long id = jsonObject.getLong("id"));
                String name = jsonObject.getString("name");
                MyClass myclass = new MyClass(id, name);

                items.add(myclass);

            } catch (JSONException e) {
                e.printStackTrace();
         }
    }
    return items;
}

Notez que StringSet dans les préférences partagées est disponible depuis l'API 11.


J'ai résolu mon problème. Je veux ajouter quelque chose. Pour la première utilisation, nous devons vérifier si l'ensemble est nul. if (set! = null) {for (String s: set) {..}}
xevser

@xevser J'ai ajouté une vérification nulle comme suggéré. Merci.
Micer

6

Utilisation de la bibliothèque Gson:

dependencies {
compile 'com.google.code.gson:gson:2.8.2'
}

Boutique:

Gson gson = new Gson();
//Your json response object value store in json object
JSONObject jsonObject = response.getJSONObject();
//Convert json object to string
String json = gson.toJson(jsonObject);
//Store in the sharedpreference
getPrefs().setUserJson(json);

Récupérer:

String json = getPrefs().getUserJson();

Le colis n'est pas un mécanisme de sérialisation à usage général. Cette classe (et l'API Parcelable correspondante pour placer des objets arbitraires dans une parcelle) est conçue comme un transport IPC hautes performances. En tant que tel, il n'est pas approprié de placer des données de parcelle dans un stockage persistant: des modifications dans l'implémentation sous-jacente de l'une des données du colis peuvent rendre les données plus anciennes illisibles.
Marcos Vasconcelos le

1

Vous pouvez le faire en utilisant la PowerPreferencebibliothèque en 3 étapes faciles!

https://github.com/AliAsadi/PowerPreference

1. Créer un objet

Object obj = new Object();

2. Écrire selon la préférence partagée

PowerPreference.getDefaultFile().put("object",obj);

3. Obtenir l'objet

Object obj = PowerPreference.getDefaultFile()
                            .getObject("object", Object.class);

0

En utilisant cet objet -> TinyDB - Android-Shared-Preferences-Turbo c'est très simple. vous pouvez enregistrer la plupart des objets couramment utilisés avec lui comme des tableaux, des entiers, des listes de chaînes, etc.


Cool, mais je pense que cela fonctionne juste pour les types primitie (String, double, int, etc.) pas pour les objets personnalisés (POJOS)
CommonSenseCode

cela fonctionne maintenant pour les objets personnalisés, vérifiez le ReadMe, il a été mis à jour
kc ochibili

0

Vous pouvez utiliser bibliothèque Complex Preferences Android - by Felipe Silvestre pour stocker vos objets personnalisés. Fondamentalement, il utilise le mécanisme GSON pour stocker des objets.

Pour enregistrer l'objet dans les préférences:

User user = new User();
user.setName("Felipe");
user.setAge(22); 
user.setActive(true); 

ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(
     this, "mypref", MODE_PRIVATE);
complexPreferences.putObject("user", user);
complexPreferences.commit();

Et pour le récupérer:

ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(this, "mypref", MODE_PRIVATE);
User user = complexPreferences.getObject("user", User.class);

Le colis n'est pas un mécanisme de sérialisation à usage général. Cette classe (et l'API Parcelable correspondante pour placer des objets arbitraires dans une parcelle) est conçue comme un transport IPC hautes performances. En tant que tel, il n'est pas approprié de placer des données de parcelle dans un stockage persistant: des modifications dans l'implémentation sous-jacente de l'une des données du colis peuvent rendre les données plus anciennes illisibles.
Marcos Vasconcelos le

Ceci est obsolète
IgorGanapolsky

0

Vous pouvez utiliser GSON, en utilisant Gradle Build.gradle:

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

Puis dans votre code, par exemple des paires chaîne / booléen avec Kotlin:

        val nestedData = HashMap<String,Boolean>()
        for (i in 0..29) {
            nestedData.put(i.toString(), true)
        }
        val gson = Gson()
        val jsonFromMap = gson.toJson(nestedData)

Ajout à SharedPrefs:

        val sharedPrefEditor = context.getSharedPreferences(_prefName, Context.MODE_PRIVATE).edit()
        sharedPrefEditor.putString("sig_types", jsonFromMap)
        sharedPrefEditor.apply()

Maintenant, pour récupérer les données:

val gson = Gson()
val sharedPref: SharedPreferences = context.getSharedPreferences(_prefName, Context.MODE_PRIVATE)
val json = sharedPref.getString("sig_types", "false")
val type = object : TypeToken<Map<String, Boolean>>() {}.type
val map = gson.fromJson(json, type) as LinkedTreeMap<String,Boolean>
for (key in map.keys) {
     Log.i("myvalues", key.toString() + map.get(key).toString())
}

Le colis n'est pas un mécanisme de sérialisation à usage général. Cette classe (et l'API Parcelable correspondante pour placer des objets arbitraires dans une parcelle) est conçue comme un transport IPC hautes performances. En tant que tel, il n'est pas approprié de placer des données de parcelle dans un stockage persistant: des modifications dans l'implémentation sous-jacente de l'une des données du colis peuvent rendre les données plus anciennes illisibles.
Marcos Vasconcelos le

0

Préférence partagée commune (CURD) SharedPreference: pour stocker des données sous la forme de paires valeur-clé avec une classe Kotlin simple.

var sp = SharedPreference(this);

Stocker des données:

Pour stocker des données String, Int et Boolean, nous avons trois méthodes avec le même nom et des paramètres différents (surcharge de méthode).

save("key-name1","string value")
save("key-name2",int value)
save("key-name3",boolean)

Récupérer les données: pour récupérer les données stockées dans SharedPreferences, utilisez les méthodes suivantes.

sp.getValueString("user_name")
sp.getValueInt("user_id")
sp.getValueBoolean("user_session",true)

Effacer toutes les données: pour effacer toutes les SharedPreferences, utilisez le code ci-dessous.

 sp.clearSharedPreference()

Supprimer des données spécifiques:

sp.removeValue("user_name")

Classe de préférence partagée commune

import android.content.Context
import android.content.SharedPreferences

class SharedPreference(private val context: Context) {
    private val PREFS_NAME = "coredata"
    private val sharedPref: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
    //********************************************************************************************** save all
    //To Store String data
    fun save(KEY_NAME: String, text: String) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putString(KEY_NAME, text)
        editor.apply()
    }
    //..............................................................................................
    //To Store Int data
    fun save(KEY_NAME: String, value: Int) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putInt(KEY_NAME, value)
        editor.apply()
    }
    //..............................................................................................
    //To Store Boolean data
    fun save(KEY_NAME: String, status: Boolean) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putBoolean(KEY_NAME, status)
        editor.apply()
    }
    //********************************************************************************************** retrieve selected
    //To Retrieve String
    fun getValueString(KEY_NAME: String): String? {

        return sharedPref.getString(KEY_NAME, "")
    }
    //..............................................................................................
    //To Retrieve Int
    fun getValueInt(KEY_NAME: String): Int {

        return sharedPref.getInt(KEY_NAME, 0)
    }
    //..............................................................................................
    // To Retrieve Boolean
    fun getValueBoolean(KEY_NAME: String, defaultValue: Boolean): Boolean {

        return sharedPref.getBoolean(KEY_NAME, defaultValue)
    }
    //********************************************************************************************** delete all
    // To clear all data
    fun clearSharedPreference() {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.clear()
        editor.apply()
    }
    //********************************************************************************************** delete selected
    // To remove a specific data
    fun removeValue(KEY_NAME: String) {
        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.remove(KEY_NAME)
        editor.apply()
    }
}

Blog: https://androidkeynotes.blogspot.com/2020/02/shared-preference.html


-2

Il n'y a aucun moyen de stocker des objets dans SharedPreferences, ce que j'ai fait est de créer une classe publique, de mettre tous les paramètres dont j'ai besoin et de créer des setters et des getters, j'ai pu accéder à mes objets,


-3

Avez-vous besoin de récupérer l'objet même après la fermeture de l'application ou juste pendant son exécution?

Vous pouvez le stocker dans une base de données.
Ou créez simplement une classe Application personnalisée.

public class MyApplication extends Application {

    private static Object mMyObject;
    // static getter & setter
    ...
}

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application ... android:name=".MyApplication">
        <activity ... />
        ...
    </application>
    ...
</manifest>

Et puis de toutes les activités faites:

((MyApplication) getApplication).getMyObject();

Pas vraiment le meilleur moyen mais ça marche.


-6

Oui, vous pouvez stocker et récupérer l'objet à l'aide de Sharedpreference

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.