Come Android SharedPreferences salva / archivia l'oggetto


217

Dobbiamo ottenere oggetti utente in molti luoghi, che contengono molti campi. Dopo il login, voglio salvare / archiviare questi oggetti utente. Come possiamo implementare questo tipo di scenario?

Non riesco a memorizzarlo in questo modo:

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

quale tipo di dati vuoi archiviare?
Ilango j


Cosa intendevi con ~ " e oggetto esecutivo "? Controlla la grammatica prima di pubblicare su StackOverflow.
IgorGanapolsky,

Puoi usare questa libreria che ha molte funzionalità ... github.com/moinkhan-in/PreferenceSpider
Moinkhan

Risposte:


549

Puoi usare gson.jar per archiviare oggetti di classe in SharedPreferences . Puoi scaricare questo vaso da google-gson

Oppure aggiungi la dipendenza GSON nel tuo file Gradle:

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

Creazione di una preferenza condivisa:

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);

Salvare:

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();

Recuperare:

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

9
Grazie amico! Ma non sei corretto nella parte Salva (riga 3), il codice corretto è: String json = gson.toJson (myObject);
Cesarferreira,

Hai bisogno di tutti e 3 i barattoli? Ce ne sono 3 in quel link. . .
coolcool1994,

3
L'URL corretto per il download del vaso è: search.maven.org/…
Shajeel Afzal,

2
Questo ha un problema con riferimento circolare che porta a StackOverflowException xD Read more here stackoverflow.com/questions/10209959/...~~V~~plural~~3rd
phuwin

1
@rozina sì Gson è meglio. Prima di tutto per usare serialize, l'oggetto e ogni oggetto al suo interno devono implementare l'interfaccia serialize. Questo non è necessario per GSON. gson funziona egregiamente anche quando il tuo oggetto è un elenco di oggetti.
Neville Nazerane,

36

Per aggiungere alla risposta di @ MuhammadAamirALi, puoi usare Gson per salvare e recuperare un elenco di oggetti

Salva l'elenco di oggetti definiti dall'utente in 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();

Ottieni l'elenco di oggetti definiti dall'utente da 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
Che cos'è "Tipo" lì? (in Ottieni elenco, 2a riga).
Gangadhar

15

So che questa discussione è un po 'vecchia. Ma pubblicherò comunque questo spero che possa aiutare qualcuno. Siamo in grado di memorizzare i campi di qualsiasi oggetto in preferenza condivisa serializzando l'oggetto su String. Qui ho usatoGSON per memorizzare qualsiasi oggetto in preferenza condivisa.

Salva oggetto in preferenza:

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();
}

Recupera oggetto dalla preferenza:

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;
}

Nota :

Ricorda di aggiungere compile 'com.google.code.gson:gson:2.6.2'adependencies tuo voto.

Esempio :

//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);

Aggiornare:

Come sottolineato da @Sharp_Edge nei commenti, la soluzione di cui sopra non funziona List .

Una leggera modifica alla firma di getSavedObjectFromPreference()- da Class<GenericClass> classTypea Type classTyperenderà generalizzata questa soluzione. Firma della funzione modificata,

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

Per invocare,

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

Buona programmazione !


1
questo è stato davvero utile grazie. Per chiunque sia qui a cui interessa commentare ... devo inserire la chiamata per saveObjectToSharedPreference in onSaveInstanceState? Ora ce l'ho su onSaveInstanceState ma, dato che la mia app sta raccogliendo dati in tempo reale ogni 10 secondi, ottengo un singhiozzo ogni tanto e l'oggetto che sto salvando con saveObjectToSharedPreference perde alcune letture. Tutti i pensieri sono ben accetti.
Frank Zappa,

hey @FrankZappa, perdonami non completamente capire il vostro problema, ma qui si va, provare a utilizzare commital posto di apply. Potrebbe aiutarti.
tpk,

Grazie. Vorrei provare a spiegare. La mia app Android raccoglie i dati in tempo reale circa ogni 10 secondi. Questa raccolta di dati non utilizza oggetti, ma solo variabili e logiche globali. Successivamente i dati vengono quindi riepilogati e archiviati in un oggetto Java. Uso il metodo sopra descritto per archiviare e recuperare il mio oggetto Java in / tramite SharedPreferences perché a) per quanto ne so non riesco a memorizzare oggetti in onSavedInstanceState eb) quando lo schermo ruota il mio oggetto viene distrutto e ricreato. Pertanto, sto usando il tuo approccio SharedPrefs, quindi quando lo schermo viene ruotato il mio oggetto non perde i suoi valori. (cont.)
Frank Zappa,

Ho inserito la routine saveObjectToSharedPreferences in onSaveInstanceState. Ho inserito la routine getSavedObjectFromPreference in onRestoreInstanceState. Tuttavia, ho testato e ho ancora ricevuto una serie di aggiornamenti di oggetti mancanti a causa della rotazione dello schermo. Pertanto, dovrei spostare la chiamata per saveObjectToSharedPreferences più vicino alla mia logica attuale? Infine, a quale metodo si impegna e applica?
Frank Zappa,

1
@ 2943 La tua soluzione sembra fantastica, ma se ho un elenco, ad esempio, List<CustomClass>come dovrei farlo? getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class)non accetta List<CustomClass>.class:(
Sharp Edge

6

Meglio è fare un globale Constants classe per salvare chiavi o variabili per recuperare o salvare i dati.

Per salvare i dati chiama questo metodo per salvare i dati da ogni luogo.

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

Usalo per ottenere dati.

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

e un metodo simile a questo farà il trucco

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;
}

Per recuperare i dati, cosa passo come 'variabile' e 'defaultValue'?
Alex,

Mai e poi mai creare una classe Costanti. Rende il tuo codice altamente accoppiato e disperso allo stesso tempo.
Miha_x64,

5

Prova questo modo migliore:

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();
    }

}

Scrivi il valore:

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

E ottieni valore usando:

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

2
Cosa ha a che fare con il salvataggio di un oggetto in SharedPreferences su Android?
IgorGanapolsky,

Maggiori informazioni su come lavorare con le preferenze condivise sono disponibili su stackoverflow.com/a/2614771/1815624 nota che potresti voler usare al return PreferenceManager.getDefaultSharedPreferences(context);posto direturn context.getSharedPreferences(PREF_NAME, MODE);
CrandellWS il

3

Non hai dichiarato cosa fai con l' prefsEditoroggetto dopo questo, ma per mantenere i dati delle preferenze, devi anche usare:

prefsEditor.commit();

2

Vedi qui, questo può aiutarti:

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
Potresti spiegare il codice un po 'di più in quanto questo attualmente rappresenta solo "un mucchio di codice".
Werner,

1

Un altro modo per salvare e ripristinare un oggetto dalle preferenze condivise di Android senza utilizzare il formato 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

Puoi salvare l'oggetto nelle preferenze senza usare alcuna libreria, prima di tutto la tua classe di oggetti deve implementare 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;
}

}

Quindi puoi facilmente usare questi due metodi per convertire l'oggetto in stringa e stringa in oggetto:

 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;
}

Salvare:

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

Leggere

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

È possibile evitare la codifica Base64 e l'escaping XML semplicemente scrivendo questi byte in un file separato.
Miha_x64,

1

Passaggio 1: copia incolla queste due funzioni nel tuo file 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);
    }

Passaggio 2: per salvare utilizzare:

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

per recuperare utilizzare:

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

Puoi impostare diverse preferenze condivise usando nomi di chiavi diversi come:

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

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

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

1

Se vuoi archiviare l'intero Oggetto che ricevi in ​​risposta, può farlo facendo qualcosa del tipo,

Prima di tutto crea un metodo che converta il tuo JSON in una stringa nella tua classe util come di seguito.

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

Quindi nella classe Preferenze condivise Fai qualcosa del tipo,

 public void storeLoginResponse(yourResponseClass objName) {

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

e quindi creare un metodo per 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();
    }
}

Quindi basta chiamare il primo metodo quando si ottiene risposta e il secondo quando è necessario ottenere dati da preferenze di condivisione come

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

È tutto.

Spero che ti possa aiutare.

Happy Coding();


1

Ho avuto problemi a utilizzare la risposta accettata per accedere ai dati sulle preferenze condivise tra le attività. In questi passaggi, si dà un nome a getSharedPreferences per accedervi.

Aggiungere la seguente dipendenza nel file build.gradel (Modulo: app) in Script di livello:

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

Salvare:

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();

Per recuperare in un'altra attività:

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'

spero che questo ti aiuti :)


1

Ecco come usare le proprietà delegate di Kotlin che ho raccolto da qui , ma espanso e consente un semplice meccanismo per ottenere / impostare le proprietà SharedPreference.

Per String, Int, Long, Floato Boolean, utilizza il getter standard di SharePreference (s) e setter (s). Tuttavia, per tutte le altre classi di dati, utilizza GSON per serializzare aString , per il setter. Quindi deserializza l'oggetto dati, per il getter.

Simile ad altre soluzioni, ciò richiede l'aggiunta di GSON come dipendenza nel file gradle:

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

Ecco un esempio di una semplice classe di dati che vorremmo poter salvare e archiviare in SharedPreferences:

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

Ecco la classe che implementa i delegati di proprietà:

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"
    }
}

Nota: non è necessario aggiornare nulla in sealed class. Le proprietà delegati sono oggetto / Singletons UserPreferenceProperty, NullableUserPreferencePropertyeFirstTimeUser .

Per configurare un nuovo oggetto dati per il salvataggio / recupero da SharedPreferences, ora è facile come aggiungere quattro righe:

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

Infine, puoi leggere / scrivere valori su SharedPreferences semplicemente usando la byparola chiave:

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

Se il tuo oggetto è complesso, suggerirei di serializzarlo / XML / JSON e di salvare tali contenuti sulla scheda SD. Puoi trovare ulteriori informazioni su come salvare nella memoria esterna qui: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal


Non è necessario un permesso aggiuntivo (scheda SD)?
rishabh,

Sì, dal momento che avresti scritto sulla scheda SD.
trenpixster,

1
Dalla mia esperienza, minori sono le autorizzazioni richieste all'utente, meglio è. La scheda SD dovrebbe essere una scelta secondaria, se l'utilizzo di Gson come indicato sopra non è un'opzione praticabile.
rishabh

Sì, sono anche d'accordo con quello; Solo se il risultato JSON è abbastanza grande la scheda SD dovrebbe essere un'opzione. Direi che è un compromesso.
trenpixster,

0

ci sono due file risolti per tutti i tuoi problemi sulle preferenze condivise

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);
    }
}

ora puoi salvare, rimuovere o ottenere like,

-Salva

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

-rimuovere

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

-ottenere

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

0

Archivia i dati in SharedPreference

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

0

La mia classe utils per la lista di salvataggio in 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);
    }
}

utilizzando

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

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

.
Codice completo dei miei programmi di utilità // controlla usando l'esempio in Codice attività


0

Ho usato Jackson per conservare i miei oggetti ( Jackson ).

Aggiunta la libreria jackson per il 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'

La mia classe di test:

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

Oggetto Java a JSON:

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

Memorizzalo nelle preferenze condivise:

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

Ripristina dalle preferenze condivise:

ObjectMapper objectMapper = new ObjectMapper();
Car car = objectMapper.readValue(preferences.car().get(), Car.class);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.