web-dev-qa-db-fra.com

Android - SharedPreferences avec un objet sérialisable

Je sais que SharedPreferences a putString(), putFloat(), putLong(), putInt() et putBoolean(). Mais j'ai besoin de stocker un objet de type Serializable dans SharedPreferences. Comment puis-je atteindre cet objectif?

46
Carnal

En bref, vous ne pouvez pas, essayez de sérialiser votre objet dans un fichier privé, cela revient au même. exemple de classe ci-dessous:

import Java.io.FileInputStream;
import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.ObjectInputStream;
import Java.io.ObjectOutputStream;

import Android.app.Activity;
import Android.content.Context;

/**
 *
 * Writes/reads an object to/from a private local file
 * 
 *
 */
public class LocalPersistence {


    /**
     * 
     * @param context
     * @param object
     * @param filename
     */
    public static void witeObjectToFile(Context context, Object object, String filename) {

        ObjectOutputStream objectOut = null;
        try {

            FileOutputStream fileOut = context.openFileOutput(filename, Activity.MODE_PRIVATE);
            objectOut = new ObjectOutputStream(fileOut);
            objectOut.writeObject(object);
            fileOut.getFD().sync();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (objectOut != null) {
                try {
                    objectOut.close();
                } catch (IOException e) {
                    // do nowt
                }
            }
        }
    }


    /**
     * 
     * @param context
     * @param filename
     * @return
     */
    public static Object readObjectFromFile(Context context, String filename) {

        ObjectInputStream objectIn = null;
        Object object = null;
        try {

            FileInputStream fileIn = context.getApplicationContext().openFileInput(filename);
            objectIn = new ObjectInputStream(fileIn);
            object = objectIn.readObject();

        } catch (FileNotFoundException e) {
            // Do nothing
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (objectIn != null) {
                try {
                    objectIn.close();
                } catch (IOException e) {
                    // do nowt
                }
            }
        }

        return object;
    }

}
47
Chris.D

La réponse acceptée est trompeuse, nous pouvons stocker un objet sérialisable dans SharedPreferences en utilisant GSON. En savoir plus à ce sujet sur google-gson .

vous pouvez ajouter une dépendance GSON dans le fichier Gradle avec:

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

Voici l'extrait:

Créez d'abord vos préférences partagées habituelles:

//Creating a shared preference
SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);

Enregistrement d'un objet sérialisable à préférence:

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

Obtenez un objet sérialisable de préférence:

Gson gson = new Gson();
String json = mPrefs.getString("SerializableObject", "");
yourSerializableObject = gson.fromJson(json, YourSerializableObject.class);
27

Si votre objet est un POJO simple, vous pouvez convertir l'objet en chaîne JSON et l'enregistrer dans les préférences partagées avec putString ().

19
user2139213

Il est possible de le faire sans fichier.

Je sérialise les informations en base64 et comme ça, je suis capable de les enregistrer sous forme de chaîne dans les préférences.

Le code suivant est la sérialisation d'un objet sérialisable en chaîne base64 et vice versa: import Android.util.Base64;

import Java.io.ByteArrayInputStream;
import Java.io.ByteArrayOutputStream;
import Java.io.IOException;
import Java.io.ObjectInputStream;
import Java.io.ObjectOutputStream;
import Java.io.Serializable;


public class ObjectSerializerHelper {
    static public String objectToString(Serializable 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;
    }

    @SuppressWarnings("unchecked")
    static public Serializable stringToObject(String string){
        byte[] bytes = Base64.decode(string,0);
        Serializable object = null;
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream( new ByteArrayInputStream(bytes) );
            object = (Serializable)objectInputStream.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (ClassCastException e) {
            e.printStackTrace();
        }
        return object;
    }

}
15
Elisha Sterngold

Nous pouvons créer une syntaxe facile à utiliser avec Kotlin.

@Throws(JsonIOException::class)
fun Serializable.toJson(): String {
   return Gson().toJson(this)
}

@Throws(JsonSyntaxException::class)
 fun <T> String.to(type: Class<T>): T where T : Serializable {
 return Gson().fromJson(this, type)
}

@Throws(JsonIOException::class)
fun SharedPreferences.Editor.putSerializable(key: String, o: Serializable?) = apply {
   putString(key, o?.toJson())
}

@Throws(JsonSyntaxException::class)
   fun <T> SharedPreferences.getSerializable(key: String, type: Class<T>): T? where T : Serializable {
    return getString(key, null)?.to(type)
}

puis enregistrez tout Serializable dans SharedPreferences en utilisant une fonction get/put() similaire

Complétez Gist ici Enregistrer les sérialisables dans les préférences partagées avec Kotlin et GSON

Comme mentionné dans d'autres réponses, vous devrez peut-être envisager la migration lorsque la structure de la classe de données change. Ou au moins devrait changer la clé que vous utilisez pour stocker.

1
Shardul